{"_id":"@giraphql/plugin-scope-auth","_rev":"53-f470d640c9c3e23fa788a1de1db97f58","name":"@giraphql/plugin-scope-auth","dist-tags":{"latest":"2.15.0","preview":"0.0.0-preview-202179204139"},"versions":{"2.0.0-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.0.0-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"@giraphql/core":"^0.20.3","graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.19.1","graphql-tag":"^2.11.0"},"gitHead":"2ce2d9f3a1c2a244b069657bfcd508b7f1adfc72","_id":"@giraphql/plugin-scope-auth@2.0.0-alpha.0","_nodeVersion":"14.15.0","_npmVersion":"lerna/3.22.1/node@v14.15.0+x64 (darwin)","dist":{"integrity":"sha512-PUKbOVZvzQperacjg6BiQOoVyDvaLgCOOCfgMnnJ+OSTx0kgWEPvk2k4Pj9hRidy6itbtKL3GX6sSzxklETBoQ==","shasum":"c89d781fa5bf447cc6d9281ebc51fab2a805124b","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.0-alpha.0.tgz","fileCount":58,"unpackedSize":352553,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgI3i+CRA9TVsSAnZWagAAal4P+wc8815J/G9Q5Ksybflr\nL12uJd/DqX/+905ueGiBMeXMp8RGWfUmo7NVXg/YRGguQbhwQDMPQPOxRdB6\nJKIkkcyIIAZ9ORqMSmKK9WFe5i8Dl/l7iUbWkZEgV1UBJd7br/DYtozyixNK\nVVnZqJfjPY7gq2iubJbHjY4eQY6+RfihIbjZgGMF+yCqhz5+xfDmhU1rtS1L\n595/7VzqL0hd8xw736KSFLx/U5MNF7oqTad4+ESYtF2ushdrcun3Nn4YJ2ct\nT1CZTfvSUUzUJUFOjNL7/tUKzHHyX/cPMnAs8CtuS2uYUqzlbD3E0BzaDRp5\nl2cFy+gcRG6zRx+4iKGDGXKrJsrhIOruXNOfqLccouLaJwLnyG/MjlxpIPLX\njLlz10D/r2cnLDIhDj7X5KFkLrI4knTqapZ2yHABTLXsgDzoZ3UbmZlNSzOb\ng0yHvo1HA7NUO1Z1iM6oADB0FDtqM0WCadXgRKVaY5K7rjDp31q/qTdz3vyY\nLPZS+jXlmHPXtXuZdNxn7H8X2Xl+Pz7qyePUYNhxuPyJH4Uw2y6FkslXBuzv\n15lD27zCJk0x03B+etMZsPkeSoN5GZSOdh8pEPUYqFb4pzX7SfwrC6cQBIC3\nUVPVJzU7V/+1x5E7+j5ey1x7Zw3a6e41+DqadJSvqbxWre7k1gW/wTjvuk8m\nKWO6\r\n=b/c2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA0c6CIqTkjOg7eL+qQFgcPFjzYT1UWVpCka/jJj7GNxAiEA3BhViQD5SHA6PiBZFOjCxK9RBCVuDt2RoeS1hpoZ000="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.0-alpha.0_1612937406287_0.47947987623250676"},"_hasShrinkwrap":false},"2.0.0":{"name":"@giraphql/plugin-scope-auth","version":"2.0.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.21.0","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"c887e569cdb670ad3182dfdfb4a329e43744916d","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.0","_nodeVersion":"14.15.0","_npmVersion":"lerna/3.22.1/node@v14.15.0+x64 (darwin)","dist":{"integrity":"sha512-pNn1l5W0sAqXSfgdx5VPIYCQMjDOCaRMpCDdnboDdlxrszwG78FoQAMJBwqlLuok3A0EZwlXk3/eoIZ139+sKw==","shasum":"07b4dd9bfb7174b1a6b2b0858d4e786ce4646345","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.0.tgz","fileCount":64,"unpackedSize":373428,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgKz1sCRA9TVsSAnZWagAAe1MP/09IoIf0iiRf0ZFg59QL\nEKjozCQ+y2HCpEyo5e3s1aQXvbmwmLzMvGLLIFM9BQG4AOgrNgFOMDF78sL9\nEl9e7MWqmwgXNjq37GzMcuByQvbNVEQKe4oNNWOWKy/7sPdVTR1Z166469Cp\nB5OjOlEog7DcQXDo79eW60KDmAxWX0m5xTG6v4IBzPAx91GmHTt8ZwA3A2Mv\nMyDEshq4WnsafrFG2edazV7e+ItCAEeQXeJWzHa7iBCvGtP2zPan3aZnaQPz\nmfqsQRIOfg2XiA5A1Q6VKE0+FA0k7vaHZrfOEGPnx4o8STTajQtm+qL/FZnd\noErc1dl1Zk7GSeYV5VLmmt0QU9yEZwnL/P8tUPVSyoz7vV5ZHzXlzdwIVX4O\n2witkCT0WJG8Pq3r5Dusn9wPP2btXy5sb1FiVOPd8DYjrJKPXWvj7fO+a13n\nZEyP+A8+ASa3XqkQH7y6ZpprBlPM+WJdlFIE1zajjdBB1OGjYDFwe5WZr0qn\n+KScnLAxTKckNBNB9pJ5Dl/9mpEVbKMUXqFIOlarVEuUizVg5JP4cf2oMExQ\ns3xkyjuuIwJkLJ6tjms5MCuJuydBVCyep4hq7i51799WMhvapoH9Z+mjgDlB\nxfSJmPV12xjR36/anY57oJe/fm/A+LHolHfJ2UQBfV24MehWEEJ623daeFlY\nqpu6\r\n=PfMa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFfZ2DEBC1JVhY4aWDrSWUgUpVO1gTRs7g0DSpVyYqncAiBd9aKaP9pra6Z6rp6E0eOzVSTW5yZkV3jGPZag8jB42w=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.0_1613446507776_0.5576393974331779"},"_hasShrinkwrap":false},"2.0.1":{"name":"@giraphql/plugin-scope-auth","version":"2.0.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.21.0","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"c4fa73a16fb6fc435b5592d21d8568b2559e866e","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.1","_nodeVersion":"14.15.0","_npmVersion":"lerna/3.22.1/node@v14.15.0+x64 (darwin)","dist":{"integrity":"sha512-M/mUmDAfxNkQZygm/Txlm5oB9qrtuaPq5abI0HIidN/rOu3pAn+ft16dvs/ITNHk/nemaX0U0cMhrx2fE/TbDw==","shasum":"dcb194aa46619b75d26a61e59bafb7f19ad46d3f","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.1.tgz","fileCount":64,"unpackedSize":373525,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgMCiRCRA9TVsSAnZWagAAY9UP/0RqktpG2uazRHzL+U8T\n4JCOqEojnDcHjFv9ieCizXMN0CiMyJm2/JxRhJ2BZuQFIOQxs9kSCakm8Ehx\nLiqA/4iSBXEtdMMQRTxn1VkERAauWS03WzHaHxOV3PrWkVieKvaKn3TMEwzV\np1qrshD5ker4/a8blV4EXHj2aE4rNVHngce+Y7oPIQxAtIgaUjNpPMpNDYPR\nSqTdKVVd3c8YkkkLP05QMnTDtduedO5Qg8um0RAQdHAwFQXPTosmcR/WidNk\nEv0/zK1Kjgr0J9uTpPKNElsufdM0OQqaAQtlJQ9erKg2sqAsQNQSgITg5tpO\nOyEHKAxfIdXf++/tGTDVG2PlPLsApcAVq3Gjim7TjNtvW5vSlCMzIIXPlPp/\nsyjfywHF0eUqyarvNsX1zrS/3O95Cs9Pzwc5zASOvTQ1T9ksjGr+3+ubAOMx\nL0SJ934FaMfuLMYDTYLX+B7BvYIn6/Vy/sHzF2ISjlNOJ0P0VA2ZhqztOqw7\n+intay5FJ5GAzNIlBXOcxyRn1Eud5DqOMl3uFSGZy7+sL5aGMBD+pImhUaRI\nhnQ3C60cbL/sS4XKbqYXUUFfigyU6s8MeKlSV49t3n3aje5o90Y9+eGeMTxB\na4+gQ7M484cZBAwe8G9e1gy2/gMl4wJEcpaixYm9hTONlnT3JG9MI2uDtexc\nf3sX\r\n=2LSD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD42wzFtlLIXYSuWfO1Tb/bcKZfT+LPwQMMoLK9OG4CxwIgHyCrGCuB/9TTILXtGGVcG0Be66rvRf89ComwWCJr0lg="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.1_1613768848958_0.26854044711120384"},"_hasShrinkwrap":false},"2.0.2-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.0.2-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"84a220922983a245ccc3b656555cc8474864ab62","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.2-alpha.0","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-zN+GFe9Rmu8xvoqeLPNDJ+Z9QH4jPDRQrOLhryA5Ofal5fXfALDxCszVy8rhcufrlSEehQ9FHAgq7HSoOOrkpg==","shasum":"14593276318169cf632766dc3f79983e1e3833cc","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.2-alpha.0.tgz","fileCount":64,"unpackedSize":374455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgc+XRCRA9TVsSAnZWagAAIEIP/0pxNxw1BV8KPyk2aiOz\nVf5t+YTdIo+1vFVWatS7HY327UQJzWALboNfkKxFUDopjFWTbaLquv+O9gM7\nOowfYunPmU17SZe4XbFluVetD8rNOSmxYtUj9hWEPjm0qoGAXBbgdlUcjN4y\nlJOfnmMq/L21000PvHZVvgVSe3AiFTPRJhtfekSKMroDwJGpEH+W+LXCrrZp\nsN+EvAB4aF0w8KKCf4ciJj1KnRbqYFlQltS1zWIMR2LNLX3RzhhwHwE+oyNZ\nTxmLXmZpxbBvtFFbRM4nG3GF7M3oyXqFgPFBtQ66/9AayJ5zhdroyqwyiV+P\nkyCvg/grxaM4Vnc46ZCX693l7rooR6BlOBAGt7UFXKICBRkUSPCzZx7r9Pp2\nt6eufdCaxMoijYxvMbPVtsYmdhunSFNWgx7fwLb5iQVnkYmcPdhdD8jeulnK\nmcciAWMBq2s9LHcOjLSXD1R74sJkHnx7tiX+7FFDhc6yjcfJWR2hrAUDVzip\n7sDQdkC93NCeovVYK5v3yZpDKbfuHga6/chpNE8Jynr35CIb2pMjpn5tHUiw\nVMd446tbZ5pOYk/E6scb5MioIs2BJ7cbzNNPutM1AcRW/dH0aymyVq0gneIh\nTsv5Hp57qdegTmP/X7BbMMoEEYRuxnE1Wt6lW0HpgJJtxMtl+5EGywYdKTyf\n6Uq9\r\n=ZTkb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG3hsa7bkj+Q1TN6KO87VIKLCxjXtPK+QaJi02+7bW2qAiBggI39QpfHEZfmiQcN+EPDb47F/6sTPlx1wTX8EgTj3w=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.2-alpha.0_1618208208937_0.8304711748648907"},"_hasShrinkwrap":false},"2.0.2":{"name":"@giraphql/plugin-scope-auth","version":"2.0.2","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"d6cc87d3aec1cd9cd486defd22bd2074e30487ef","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.2","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-1uHcx4hPGBbeBG1is109jOHbJjfqcbje1JIcNtH1uDfELxdf76xZ/HxfUtVACPQgSaJ6t8VYO9jcuG1aMY/8gw==","shasum":"91b35ed8e9003cc1bc87531533c7ae8a6ba47778","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.2.tgz","fileCount":64,"unpackedSize":374544,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgeOsCCRA9TVsSAnZWagAAw3YP/iCHaNBT4t0s6N7YGzqv\n7NfNu8Lkb2T5hDol0uAKNeq6MF/MH7/YBFA4d+SDNNVbNBbCIH8DGtMrLNc8\nKVJVX6A3SgC8Jagg54QV8LiBW4dBoLAu+pZm1Y8FsTH0BDkmlJoAkm77bsQ6\nefqudbrv+2ZTarJGFa5cS8DOrw317Y5g8P6HKTmCntGG6JCAW+VhFAU/TA/s\nMAS8bTHnMCln8gAPvkta5TeYjyBFe+96PUdM97+4zjdTm1B1lJ2hvnMqSyd+\nyS5IiHy9mi9C28z0YTOufWS4gpfVsNGi3lVsNLSGvPjTDn5j0HJGR9yA+eWJ\nef7X4lPRZgouETZXp/Ik6mpgiC7yzMBbqotu2drrHVKWjESp/pqDC1si6RFz\n+P+RCHqDxFqE0tJQpsopaZ+eBwKihB0vUWBqS8Fl8l7UrOnpffYZWIl9U3L6\nJ6Mwr2GbXcLd1w9ckZ7Rbb3T4SLsgZqTXWJr0ughLHhakD9j127Vh0/ot2fv\nKUtHeNUWJ7LB9kbCurQOIn1HE7ktQ4Jby0Bkq35R3vgJetWyKeUMtl2D4577\n3vSnWtsxFPwBvkXp+ryUSoOdIOestbMgIRryKat7rR90Tj/crDFDT18dryE7\nMl9+veMp5YPLcklj9CuSm9Y54jFTYAfYJbcMNZYkbNJ8xdhrbTDlYNNGJHJ1\n8gCR\r\n=+CId\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbcbsojiXUCeiGb34Dagvm9mDQGIw9KDNkq1Uisp1QCAIgcLxUXHppksN0LEImCpkiG72yOEjEe7jlnFwHbrP8QKw="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.2_1618537217997_0.6916001232823674"},"_hasShrinkwrap":false},"2.0.3":{"name":"@giraphql/plugin-scope-auth","version":"2.0.3","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"52a33fae5357a62e59c8ed18dba4129ed8e59074","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.3","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-oRrfQoBTckVYekR07Vb8MiUgh8kt137nKy109N0t1KaZkw8irnpw8T+VkHlGG1gOcxnYA1BVd6rx76sR8t68Sg==","shasum":"6839b4062ee86eb4f61772220f5da7eb8f4fbc92","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.3.tgz","fileCount":64,"unpackedSize":374088,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgjhr7CRA9TVsSAnZWagAAy3AP/i0wiuOkw/9QCEVJRqHQ\nIIknrRPNQGzEJi0IbGfspkdc2BYR1vdn6Xc4NfSV3Jgmo0BneM6eG1F84/Rn\nk0/h1He6aPESv1Ela/ALf3ZCF4oAwEPK3TF8Z8QM65dzS39OEmaKK6rhTJK6\ney3lwf5Q26qtotBk2kpRX5p5lZbZ0CB0PgsM2rrrarKOlZW1g/epsZvtMg+r\neMbMKAVyo2CmLjCTv8iPPJgJAjNbW10JRXYzD9sRmjE1jxnKmGzKKTAgybVR\njilc8vx3A6NMmUMmbFQkwR5Y/xdRlVG8oa8AaE/BdQjzJ0/ecrOZ81/ReE69\nIRP/mF8njLSKPIvDfALwdhFP0lg46ImJBhWtAZilsPRsp4pcvuNBtplTlTkt\n2AgXDilTS4oS+GKK3h+Ww9B96a2SiRSGxXrJjdyJHHalwWj1qpdPIrrZmr09\nG61c0xrgtfBrdJbQTR+QTw1DCFXy3+Yl5ihlVMcI3HYUBm5HHnY+LhTY5cnO\nK2JGIlPhilg4qkrGvq1x8NYX4sV6OVgMlT5CVLhzNaPPd0Q9uSD3epJARE5H\n3CQgdlHSw5Izl3RqjPMGrjm0fHNauqyixN3HElZq9gYyg71d8iUOVjasFGf/\nGByU91F8yLPpE4KwaRIs/EzHexglg3IyG0wbxzimR857Djk1AOoXWwfK1wFW\n/jV2\r\n=KejF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCm964jZhfy734NriQMwHgPWamIDZAyaFnLJFnyqFogTwIgHyLFxTyBied8cdh+eP9tTF2ZHkjvHJwMNpCoTvfl2iY="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.3_1619925754915_0.678842795191855"},"_hasShrinkwrap":false},"2.0.4":{"name":"@giraphql/plugin-scope-auth","version":"2.0.4","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"9af4ad3eddb13e94bd60a5efd8754fe678abf639","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.0.4","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-d4ZtjTBUujBJ9p9Tsjt5zUVdMncFqpAm8agi7GkbsmS58nHQrWv8CKQTTvXRn9EUOMx19aR7rgq7KuIH+Hzpfw==","shasum":"201458811edefd3fb88c4b95c1affb068c3e6675","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.0.4.tgz","fileCount":64,"unpackedSize":377992,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgjidDCRA9TVsSAnZWagAA0vQP/i9qACKmTPBxmZzwewsG\nf2VmMU6JMGo3nm4bR6eNEpageFMQcPZx3uZ4Xf3gsS3c+e02t96/WF/iHwRO\ndcIizG0PGOGiVTjpTFo4zLs28siwp0LI1brcggGAXQB+7BtvxtJISJXR/jaO\nu/dMmK8YPfM7VVwB77wULajCpN5lAlcAYfbONtMTX0Dbee76ltrA1fs++861\nbiLu2fk8S7RQh9MTciZD7sJ5iMn6g0z6l58v2XnJLqEEQQsXG6eA9skHIqdf\nQLYjDdwKiTvRyWqCx0a95keTpoEgIqm/n0343SBrE7jPz/H26h0JoXtGKqTN\nEM7M2dhc0oTerLhXnebDPRpWrBWnBBCFyLQAr62DiyVhD0GceZCpCHr/FM9W\nj4G+VbOeVGTUVGJd81KM5YpXUnNk7r1uv+5YtKNJ1FmdMOOdrGGIqnaDEFHQ\nLXwlAGsZNDhs5fSuvXQjq9n8i4pECtP4FAvOLVTPCXYKzPtOQFhLjddSUwsB\nswOXeNPPxFqdIXrmQI41rQyAPVqL3J6ONaitldt/4lCmEaB7XXjlss11HWUd\n2IjuDBv29aNvBb4bQyPbvDC3+FNSqKA8YvPt688cKZxkmzfOtD8m/Bq3vZcV\nHAxtKOmmO0yD1eqEAMJr06sZd3rCBNzjZkKc0FEy+TB4DcNmi1DqXrPa0y6K\nz3UA\r\n=/gw6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE0+v0HAzgayiQIKTMbQcXM+XiGzE7yHydiITCuoZR/6AiB7gkE7VdHWu6YOypysmFbN4Np1u25ncu6V72SIa6RAKA=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.0.4_1619928898628_0.6285081181686092"},"_hasShrinkwrap":false},"2.1.0-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.1.0-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"c71c98c6a2e17142916ea05d52253e2c7c472062","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.1.0-alpha.0","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-4qy5BJp6f+tLT/ARvotmzTQ/q1fW33SdY5ukl2dBdCWWdWEhpdEyEbgj38yiLdmI1qJiLm4F/NNbnt8lO0ehyw==","shasum":"5873f5ebd6d8bc15f77f0930e6c7fa0ed7858088","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.1.0-alpha.0.tgz","fileCount":27,"unpackedSize":115087,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgkySGCRA9TVsSAnZWagAAstoP/1J+RlBd/fSALSb3CNuA\nxQl+FJr+h3p6M66Gczo7qWBPjMrb9f7JK2Jg6y6KsoOFwFB5Rh5vnXITkmN3\nsHAVx2I/gziIAcOSAAAoDK3es+0hUeZKkjDD2zQPBK9CObob00K8uGfu8pB5\nEFHH/gv3JFDuUFfuYTXc8nihJF/1mxN+PrfTwUnF3NHjypaq/U5pK1WWCQor\niNSmO1qsht7Znvfn3cmF0RXgstg778TKpAvsJKTjNPEQx1wn+2M/Wsz8LsSk\nm0eGJWtV+ZuhFeV1Cct7+3cl73QxcE+tCHumejv82enwaOKjaynAYUSyJt7s\nbhBdwBfqbRNiqI5gI2P6x06fx0+cVr11rgjhBaVx9WuvtzXCu6YD871zyQTJ\n7/fN7F7BDAPnDm0SsfZ/XS9SeuqIIUXtDAGLUBglA3WXgE/NvpWD1UE7o3nH\nZ7bBACF8bzbYJPe+BaGzlSzyXajmO8w1uRCNgrVsD9ecm37ywtXujRki+BJW\n+6a4jzX7qYfxGBxOqYeQ4G6E8ganpg4vF1nVfRkkU/zLE/Z37qkM4yJd5FJZ\nqPuKroiu075TLHw3u2/l8v20Cq6t5pbJ6HAc4t2P6IYsxQM8l5e9LjAbX+Xh\n/U2lxF0kZgpOsPj/mwUfX4MZ0idHUpzBDINRtDNM8BLjQnweRNXleGUrqjGf\nZw+O\r\n=vq+X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBoZdpubS8jolw6mbIx4/NPP/mxlc5S5THT2dqPTM5+GAiB8jkniW+2NVwuMZJBiqV2yqFjxuW7rEChni51rEs+kNQ=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.1.0-alpha.0_1620255878196_0.07411959798922951"},"_hasShrinkwrap":false},"2.2.0":{"name":"@giraphql/plugin-scope-auth","version":"2.2.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"eee407d1ce2277f8aeabdab91972d9aaa31e70d6","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.0","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-4ZNGUzY61NexgFSKXAMgzLM/wpEIQ8JmCpHtNgdI0CEDHr3YlenjkEgLW/c/3Ou591QO5bB1ZXVZCIX4DDFNtA==","shasum":"4bf597590351676343fc41f6c4895ab125196889","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.0.tgz","fileCount":64,"unpackedSize":396080,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgmXUGCRA9TVsSAnZWagAADwIP/0vE1FyIaK1aWmU7ftg7\n55U+R0gnAWF8nzaXX+ItH4jXBLaBHeVRsorURrwdq+qz5IFFsN9S1DqYB6ra\nhB55ZBALPYX6G0qaSGrweGXljR422kAySPQqR/SO5MvZ/Xa/eet9rfYNnF3w\nqL9JncS3tNZ7Rtb+DF99RrI0d2Ldy9dkmnfYSkasDDu7VM4I6JFswUzwGQoV\nfusfHyBTW5SLIf5Etl5QaYBKioG0V5GxOSGuKAJPiOS/TkeecNRMNhzRIBqa\n9XVvUP741s1UYMG8utLA9JsUZitPAkTAslxN3oPdCBLrx358VxgjR2qCd3Lx\nu/az1RiVbjY46nRYiks9EYPO/sYigxTwDZUquSu74Hhq4VCy9Ui8UiJXmxDq\nwbSGAibNR54X6dS0gQEw9Jji+XmqYaF89MG5z8FxQa8jRJXlasMz9Z+6frcQ\nexlxGLtLUNnugAWbZ8EHh2bchm0tFZ5IAjaYeRC/1LCUUl7jmuoWNoYs7El7\n39X0R5YMuyTA6NlX5NAcVSEcfvN0nX66TtAYnZYxEFQk1uoPkL+svGTeN7ak\nVsxcPoIXxPPM3wiulgkc0l0Nmaym2bXLv2kyQWZcNrEJQ056NgXoQxVIedJK\nWWedG6LNfvcH6B+TavGBJ7WX1DkfD3bTZPMDcgt3gzQqXsNbexXFphOUbytO\nDLqA\r\n=H6+9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA1mhmrk1N1de2Ze05pZoQfDo1vBx67H85vIixNpqsy4AiAfpiykH2A8IJF+tgEI15THTG/hL8NuVBtmmfzTnUECKQ=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.0_1620669702265_0.8319917688810623"},"_hasShrinkwrap":false},"2.2.1":{"name":"@giraphql/plugin-scope-auth","version":"2.2.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"3ba24d9c3fc96c7ea54f3a967019b638519b4f8a","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.1","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-3Ndff1ftkSyG4OpzYi0BuT7X14nXuK6IuSLWzhZK0DInpXLqkN2IIKaeni/DqGnplb45CZTAzJtvnlcXWCKCJA==","shasum":"75faf80cb2103f764cf6cde8e50bcc226b04618f","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.1.tgz","fileCount":64,"unpackedSize":396300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgmagzCRA9TVsSAnZWagAAaqkQAJJsUiQsRLCYsd1ujtBo\nt/HFsmFbL6zbWPnVwmgHaKPm9q06gbVlUa5RLhLnQIKHWnSInlsky9o/mbxM\nTY1DRXV5xYJ9BeF9dR0OPBxBoQMAbLly+Crb9a117CEaHDJfLCWG98g/oDcE\nHLONS73ZNQhlTBPC8ZvLHTaZYaiWz89twHsWGSk0yiotTKsNBJNs2l/FwEtn\nDJAL4tNmkO4VJvt2djzilLjqYl6iDhPnAILy69k/IrT0CbAxPhCdC9Ysby5d\nbT5enHjl2GgqoghDefIAMEwigWtE8icztlt6OKK1LGD1aLgjMYU/YqEj9kCK\nC+vYN3NtX1YXt5NjTroVrTQjtVMBeehZjPDXoihCRySVs/tzWk+tPjRZ+6Z7\nsKhGeDLlSzaoGhWuLTdp97zx/0NJ2vzd/BKy8s6TE16Xwak+VdXfwj6nW/en\nP7o2CzYGwv6x8uwznuirm8dvlf4fGvpU4+XDMuTI4D5aMMV9Ta0o9js0PIOV\nCTZ01YP4wlY4tHmFT1qFJrzLvnZukAQQH3I5P520F+U7En1HqLug7PnulgI8\nvr7QM3hX4/YaEBeLN0wV3t2TY7bT2cQ/KD2kPyk1oqIEumsuwgJ/vEApMq0C\nXPsbOZOi9whCAKTA6xmS3UYPp/prTuzY2hOvimwgltKqLe2zPivS4dvn9Jhe\nZSub\r\n=Ch8I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCshAci/34w6wFg8KT+G0bIuUKqwSyCVl5GjeQP1+aA5wIgFvMh6R5o7WMiOsfIXRHWgNv+EZ12tguRFelHvoBoIsg="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.1_1620682802990_0.4337925984895519"},"_hasShrinkwrap":false},"2.2.2":{"name":"@giraphql/plugin-scope-auth","version":"2.2.2","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"51dd6c62d6bf639e105709bb0ab3cbc0a3f149df","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.2","_nodeVersion":"14.15.5","_npmVersion":"lerna/4.0.0/node@v14.15.5+x64 (darwin)","dist":{"integrity":"sha512-nTm6/LnAhg3Ke4GpxoXJSbh/gCd4wq4qPJ4kTsYRzymVJSNvv5+0jF7lRUtOFWtee1/6XTjcBOzNs2zEreE5Hg==","shasum":"08aed472fa5ef94f661d39aa59378b78b562a79b","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.2.tgz","fileCount":100,"unpackedSize":448646,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgmanfCRA9TVsSAnZWagAAaxQP/RWkb3IwJNU47+JfUKrA\nWR/4jWYDhYuTKVfMfutDhab7E9gWIMZiaqbgzYevonJvpQqiyssGednkwEbw\nIB78r/7ZE4tlClhJas5tJIRD9215mgCngEaDDn2Z5VrT2ik06RJJr3Dv5ntP\nkXYwA/cl78gHYn2lP8zIc3qbbMlGJEGzWaqsQcexnYBkWb0wYubQtVBzr2NZ\ntttZGIgfp/BRMcRIHpwnZQytWdn/WbU+37FsKdsxaIMzDShkEv3VoS4jklUW\nGlZa6Hk/Vsed0Qzb1RGrSZ0lARCPhMBwf0jN28uTcki/YujqWckvumblIJ6q\n2spRbD9NOJPUVG6kWltnTqhsFYyq043qTT0nUyHDA1RGfizFVvD2Zzod/Udl\nb91Ee/s63eKUtyDKAOjgpf1i4eAdDwAYFcPRy1Db0XfiPJNcsnKtGiMFP+Kd\n20ZMPuEpl+So5nwU+zY5Ik29U6/lmpTIDouokn+wCWi/s2rzS9p4HUKFQ82J\n9V6gCrp1VykVoAr1A/n29gdf4kZgd6XpqMfLflogBT7xYUg864cz5JOSCcUi\n+wnankNJV0Uj5b+ccJjj39ElfOa8hepY0thBWHxBit1B7lTHoHy6xRq40zpH\nA9YNTITBnnu29eJ9+Erq6l3Ue4bc61qcmFIw9RqbxWUL5tNV2j3JnnwjGKCH\nePhc\r\n=7jNS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEBe7NaQ8D9u1C2UoQtmd9Hj06ul0iFX2kaUAFxZ2wanAiA0rtnzq+DWs8g8y3+T+d+DxrzMSUZcy5sNl7Al+YEXIA=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.2_1620683231251_0.12394284836787683"},"_hasShrinkwrap":false},"2.2.3":{"name":"@giraphql/plugin-scope-auth","version":"2.2.3","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"2.4.0","apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.3","_nodeVersion":"15.14.0","_npmVersion":"7.7.6","dist":{"integrity":"sha512-H+qkQ1dp+4xZT894Ghg5Qs5TeL2U+ilDhZhy0/GT4VM3M9q1mSc7z5jnCrib+NtDb/y6WuLX2aVOGAOC0Plvcw==","shasum":"5705b3b47e2e301ac62006561a556ef611c7d503","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.3.tgz","fileCount":100,"unpackedSize":448857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnF93CRA9TVsSAnZWagAAEBAP/iKFvp7k4h2feVl0MPb4\n03G8Eyt6vdMxi50d3hdImppxVsxyUuNG36FJHZUQD0KniLteQgoOSesNFA7/\nCwV2znNkTGdztsbmAK9wf9xjK7rhgQs3ONBs/SeFKqjBXu4HNJfnqdHIJib2\n6TohNSvir8HB0n0B/tqgRg1a/ZxrFvxDlBhyqe7y7g3s3yKELwNVYE/g3OYh\nGre+D6a0bIyA58TJlu3rTtBLQNs9mlT9zOxJAC/Yua54v9AaB+wGI7Mdkjqb\nhbSQyOpk9Z+NUXUGqWg8c/VhNcYgmOlMICExSTH7ViGke/72JUZl68MP2DyQ\ne/WXBctJwy7k5pDbRfkaVckFPFx/LQfZejYlPPaLDbrS+1WPBXqYs7Jm7A9V\nBQILSA8rJ6XNHYBOj46897SU8Shviq7ER9w3uk6KHeop1uK5bBIrop2KI++z\nrgyJjMwxoBE3P9LMGcBFgFgHPXarUgB3brPY2d61Ehlydmb05w8vUohibFA0\niIf9Ia+emf0fJub8V2UBt/vvb7xWJTYQq5DsRp9hDqXGDWHK4CKX0ueXT0Du\nA9Nm631paJpoRR9YatWCPmC60JpFtk+qvBL9WrorXj1QA7mPiSUjMrqPqFtL\nIhscrcneXxXx5qPAP/XQ3jaRgoPOPuc95t2IdLkaPwp6TyjeH6tnlgLpyVyr\nN9TR\r\n=upSi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDfOWfd3Kmj4l8gUWT5bvP2DCQJdHTsVxyxyJjYN8VzAAiB/c8m7LyjSE++QbkpQTs4bEMIyxeNeZLGf1RR+PD/AGA=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.3_1620860790974_0.8919538884898179"},"_hasShrinkwrap":false},"2.2.4":{"name":"@giraphql/plugin-scope-auth","version":"2.2.4","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"*","apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"e4d683db03b2e9430487a6ff332884e1e6d2fd2b","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.4","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-viQqcUqIxSvX1izI4FDsBthaK8KtfQdOPIzXMcs+Mr/bD/04Xo66V7ovF3wtobJ80EHr4HsWQMafrN1+tJ+WLg==","shasum":"ea42b11448e988ba02617c346f7b8c7e29fb7827","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.4.tgz","fileCount":100,"unpackedSize":449227,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnH7DCRA9TVsSAnZWagAAUhQP/3V9Nypcwaix8X9vAkWB\n4Gw+68oRiWXuZB5yY4m9rdJhx4D2pU4jhmXcV8qypTuPkvbpWAWZsgEVRUUc\nLoM62lLVPovudVWFCJloD9K9mlhBv400BAnLCXGfRoa4kY/N6pSwyFZQlFRe\nnwnVnoix8YykEw08k0cjm3L0LYXV045PGzIuB8Cn5PF/ZU6FrZjuJKWXXfsw\nfvWoWgL1MsdLqO+GYWnuNAlIQf+WhffBcag2JtqdD655nQgVxn+FDhJNqVfO\nBzcLmN65z2GQGz+ZmsEu6Q9Wn1b/bGOCCm3YY4Sn6PA9eBc3fhesldiGcDbF\nbinIsjIE8wgeBSyS9Cw3fSjHMja50nm1JkKtA/71DyS7a3cMU+fXAE6Tm747\nfORdRaPQaIdsFHjJb4N/KhrOeO3gnii3W58wu9SEUx32aylGmPs6Mx2RkzOD\nquivfuGacftoU/1QoCeQFG7wB0XsXn9w1PJeCJfqsNOPeSTZorjX3UDizDhs\nEr8o0ltWJXdTCgY4Lg1L/r0fqvSasGACO8FAvD/0vZ6D1Wtz+9kDD+Vm+HDd\n7My4Tbqya24t5v+XsvHa7cF9OLM0rOJemrjfV15+/sQVkOzYOcCuf3Pt6Lzw\n1fUmh0rTbqg6qn0JM0qIDkN+Ra7kPpy/lAYcJIGvApwVRJipJd4Wzse7y4Dk\nYZHc\r\n=v+yy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCW1VgUQCS7tUqEryo29F6xqKPNcBnEt6BEWvnrG78FFgIgGuTnK9zo3ADv8rqDR+Uqdji5KvEVMVuFKtfmT7QCvvg="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.4_1620868803148_0.5450586682073573"},"_hasShrinkwrap":false},"2.2.5":{"name":"@giraphql/plugin-scope-auth","version":"2.2.5","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.6.0","apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"fcbc90aae49e195ef84d1cc5aca3f62fccd4dc43","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.5","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-Zk2BiKYdAwAO+lFV2/Ae4fhbvDAUZm4xBh2NBnkO1XG8zorz95UFr6Of3Tng2Gu1LyRUfb5vMWeJtJBB+BvH+g==","shasum":"468d26464264e4bcccbb803092d920c7144d6acb","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.5.tgz","fileCount":100,"unpackedSize":449329,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgpEAaCRA9TVsSAnZWagAA2bcP/2McLIqrZtXwIvajUD4H\nn1t/Y3Y53GtotRyb03o1KVK/VA4uArM6fLLaRsZFetM8tpMsdw3j07Afo9Ml\nr5uvYYdZWDS/43F/OtsYxTYUrf7QB4ay4cbHm9C2nvCEs3/Xxamy4hVNXR89\nuu6TA2niuLVEHBN6hOB2zR03NcH49XrA6F3XvIqTvBuXRObM7U1A7fTUvqOz\nzPMPAtzW6fABjcBbewbR13RV0q0Nr0tTaB0RHWjHvaRqZ7GiIMaMIxqsww21\nTW3kV7bZsxEcLxAJtmMmTZinYR5l2QYKiYO2MY0NCqfvuFJTnuKvq7Hoz1Ry\np1YAGE6XHimBsOSPFdgDgSWS1jgezXdBdxBcCrnzreF+LuRRoFYucD6UKXoS\nQw2SBJVEUD2q0As2KvQt0P0icyo4FaXgsxHC+ZoFaY0aRY+AOyrwBCjou+n1\npXMdVSfdJeEsjWY5d8M/iNLLTAZh4d77CpeSijmwAlplp+001vXpRuSXqmup\nK0kKQ5ummdmhFToGbiOiP15555ZjScs6Ahgolhjml1INCyDUW4CoDacGH26L\nBJvgipm6qy3AAxzQoop+coOwAKJ+0Cs+ZYv6yaJth21vu0YbQA6qbJZkGZnP\nRpiq62mQdDBDNlACGvLkaY2qaIDhjq/AYHiZ9wXHu6tGbWqtyXhAS0aW8wsU\ntGu8\r\n=g43I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCtTx/scQTV32M1IkqgkRozY5Uj+ZPRX9bv7WJ0nirXFAIhAIN+WiDSb9qkE2uCwJAHSalTJN7QOSfTRuM9ufvJtoDB"}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.5_1621377049685_0.5771878964396344"},"_hasShrinkwrap":false},"2.2.6-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.2.6-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.7.0-alpha.0","apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"3abf8003277f8ae7f13ab018ffe896ea1a8dd7e8","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.6-alpha.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-nRihodwkasJO6Efu6YfvrLPTWkJCw+KcGJXQABHbUvUbCFUO96k/XnCx+NPXuCxKst1f00Y623arjcr2Fb6lvw==","shasum":"29ff9bfac49a7808aebb5fe4783c18506c938d48","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.6-alpha.0.tgz","fileCount":100,"unpackedSize":449450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwSBXCRA9TVsSAnZWagAANTEQAIep7CAjEtbgCU8E2Tkq\nj2ADPNGCWPSeaPFZTrdi5pB6cZsAVTqB78d37dP162aRpS/0Ftk1Lc9hrrSk\n9sglaqJiBye0eNmq9evcm6O93PMjP5SHOcNsuhK9/jOjdsRjYOk+IF9slkG8\nj6FDSY0B5lE50zgeAriDMu95VwRXnaI4H4wAz/+fW3CTV1RDfYttc8tizpYQ\nWW3S3btKG3V2A+fcgFBTiqZ/urUGVluTzcPpWplss7A+brWj7PrRmsetJCyQ\neynzCLoy2lJM9p4LMBNc+pYtwYfupVAZYmT0JKrjDastY+aMZNvJSnlsSvK2\nUTXESnFu2fUceYLnfIDMqFgJ5Vxbk3K1TWnQFO4BRc7yu7kNCL3JB9JZAZat\ntKOzPoEYlDAmia4eUmBCGp/fe0KwPnfAJtIgnxA2KH5nrgwuEOgdE2/u4+o2\n/aAi7LP/zCttMO70grTfYxI3BbNzMY7Rcw+D0C+o/9jsv3uirATaOeuw/zYd\nk+qglzaGLDK5SziTl29oFMnJ0h0EvngkDxR1K1RfbrgdrYiLEe1bbhFdkpOs\nm849ciEIjoh69z8otbF6JQ9bYBIIAoHkEf1ChZ+03zF74p/Q/g803U8QGNUN\n2LKvM5Nbae4yZmGHYzsfloJ8Qw3TLkFbjH4AUFPpI6mMdkyYnE66KlPCQqKK\nITcV\r\n=LAeK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBH5gb6blK8kXkKBDHC5oNZb+p3HDmQwDfJ6KA9evMDOAiEA+Ec6hbOey2HgPurtqTF0npK8Lt/T2rtx91R7Amn1tDo="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.6-alpha.0_1623269463331_0.11575615259026506"},"_hasShrinkwrap":false},"2.2.6":{"name":"@giraphql/plugin-scope-auth","version":"2.2.6","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.7.0","apollo-server":"^2.22.2","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"ebc9e62b7a38089be3a46e83683f89d187d9649d","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.2.6","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-MaoC8vNXSehSitaJBl9QvYixJTcczVnI/MdXL7oIc6uFMRnsekKcUGBZnLQ3Twky3NbuZ0pAfdOIqWAxpb0yRw==","shasum":"4ae5641403b6e590f0419fdc3a0bb0c4323ee37a","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.2.6.tgz","fileCount":100,"unpackedSize":449531,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwWMaCRA9TVsSAnZWagAApYQP/RG78qPFYBfB/OxnonkH\nvO3ZNHgFaxIQeRUoHaDgJq08isUe0T6V7nKI+/PcWmSUWT3434aITe8u0ZhY\nFEhbthRS+lqij+d3xKQY/uAHbk5JyJgFnjkc5WxWGipLpmi1PGtL3Z9IsFgQ\nFOkCUdgZjwRev27mIAN2NJVPgJnTKLY1fyz4jXLz1U7pvQPi6QdubZ1D8GyF\n8QbHMcqSVB0yo5NjvcB9iApXK986rqYkjfPTMZDtIZEBLjmk2d+z7n4MBqPV\nm7RUILrSNSGHYw2kDsj2uHG0EJYwVNraUDpvpVEsinmBN7jZ9c3fVze+t8iI\nw8ty+Rwg2GI42tRkv+NryCHnqJl948wM3jtiadQmkeASYdaNqXEn58YMdAhS\n5FxXhFnTKjnapIVNPWGpeH4h7QUARWzIamiW4+BJafg6IRFHsobLgOIaiLaC\nbzkcDb3TH4lASSkkSwSw4ovfnMsE5WSGVlvwYzS5Yy2TmVBtQSkfgcqqF5QH\nlcrOb7L/lEA2D2VIqc2mD6mkWrvhnLbDNo05dJaHXXWoQ4vZ+JoRBwLOKgCP\nDwY6XWT6LmzXO7Hf3FsLhn2OsyFVhpUBEMMIcM7J/ubDfzhawC7f8hXCx1Tc\nHLYEES9078i+zBDKzjMMd9N1NLDj73f7NDIpLGBm6xUglNg8UrT+rUPiEDuk\npbHj\r\n=XTJL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSGYGeB50DiQvpIbLH7tjutp6ta7/GAGYYzHudhTWNgwIgQOg497l/wqpajh4C5O5S0cwQ2luHHtTP8hGzvDYexUE="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.2.6_1623286554524_0.7790915633253197"},"_hasShrinkwrap":false},"2.3.0":{"name":"@giraphql/plugin-scope-auth","version":"2.3.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.8.0","apollo-server":"^2.25.0","graphql":">=15.1.0","graphql-tag":"^2.11.0"},"gitHead":"3a064a83c75af2fac8d499356fda26dfe6a9fd20","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.3.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-dS2lQcOPpN0syglFlfWxOF8NuJgXPT97gKoXIOgCQcG51CPJtmz0YnNtPb+YwgE/5d7/mSkRAC/PrNyGptJNwQ==","shasum":"2e05d2b7d80fc5afdd0c71743bb748dc9bde1375","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.3.0.tgz","fileCount":100,"unpackedSize":446435,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgww86CRA9TVsSAnZWagAARsIP/jY8O+c7v2D0uV8Xdbcl\nwWAVAwVmAiMSOklq5nFQwFspgcPj+3D4niHKLJh/9uX4B92eligtWzQG/IAJ\n+nARU8LVTquBSLKI3mlTloC1A4rV2xpqLhWH7kIv0teh5dBZQxoP9sb6GwHl\nSdiFoqdxpd7FgBs5iQSjQBE3h2K8fCSROCnESfbCVsbZ1dEZTK0ry3QsBOjo\nfqY2fm1cIP7959HQZI5f8/pKmzX4NRFxPwGkkuGLsLNe+rQIsmM/Ydot9c7+\nYM83M6pzG63QWRM6YSkyvi9o2Tdn8X+7NLb7SdWz7KwGokWdShyYjO+niArH\nY/M/rDi7485jUGyNDlnexTOPAe4lcZu0UNPUDy66Er4gy2LbU7NOIN7qZKUT\nYfAnqjIcPXqREEcXdzfPDMAScQsW7bhLDe9APMIc27vej76oX3QiCJ962AZr\na9DaqeoV8tkHCMKqtwSyoABR0Wbw2ZKKtzGDIof9G9PuAPMxcQg1pR3qlZ5C\nM4Jab+hwThNPJyELluusrQMDOq0lxwDHsjG6QJlTWx73Ef5pDSAjfHujLmNY\nGJBvme7LETRNNj0NVZgrBf/8IbUmK+u71lmC6eRCVc64V/ZpqpH/7yTwJ4MP\nCLl4tjaJdZczPjCA2RYQDdyD2MUd/QUbkLIYb1ocfuk+EpjNhI8I8U7T0Tp2\nF6SY\r\n=AawH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA1MPqBWw+wqwJfmTcfDaVCHg+9Hc9Ujb/zHOnwWhcoaAiAtU4yTvKCdSGYO8w5xDWyQ+jC97AwZkmPH2DCxmgPoSw=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.3.0_1623396153912_0.24270140469753754"},"_hasShrinkwrap":false},"2.4.0-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.4.0-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.9.0-alpha.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"b93f5e4f5541062c8edde4b82852af5e54f91e16","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.4.0-alpha.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-t+ioPDkw9Vgtskb+AmqP4vhxeoJUtm1r6bZtH8LT4gDLjLJ/0QdGBfZ2XrmotBcSL1nq2vzaIlJaIOJNn6eQYA==","shasum":"89f86652ced85e5eeeba6f0e02233e0dcfe347a5","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.4.0-alpha.0.tgz","fileCount":100,"unpackedSize":447064,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg2SIdCRA9TVsSAnZWagAAQZUQAITIpQcmkVbqVYt5jF6s\n6vDJ4ChRfKnJS7+pCsUhx7NUew7H8314PUl3Vk6QcFtQelvxXkN8Qb8yWfN/\nSIRFKWwGVydl9j61xNQNXWkIA9j5RE07a81hh8mRMo+OzoIbXIg4Bcca50jL\nmfcwoBoD21DwV2D3QwOH0naotBxa+MlxEYJ65JDUYvZKhUM2sVF7/L4UUlpc\neh/yMX2LQMc9nDReFz2RsACFLz64/rCYRiMK7/zC7TCJDAkovIHRjxrc0mCV\nnFSUiJZLXRCrKDLNdYAfaN9MIlUEbuoz5Z0RdckHupLiz73CqSP7ck/PNac+\n6eWobSUE0qmLjWrK8b7diPWI20/j2h/C5JS2wEuI5lZTA7KXDWwlhXwXRzHj\niWbRw8YqfahxzLLUb3sx3jqBA/hx4FeWTcqpA5gZWfnIWL8RsUWjl2CZDfkX\n79TBult9wssyP2GgMKA976WO9rXIyPMQrKMRZvELzUrb/J8zfdoubh2mxAAc\n1FKQc8uXXERZnTNebtohGxvRG2o5wTw7YVjqPNVUY2EtV9488u1Wmxj5+kQN\ncSNRssSsBUjzKR15YPQNEoQsRIQA6D35iQ0n0/faFf2moQY7RwY7XNq0lbw9\nsgZ54vb0r2TDmBHKqUdJL811jDqv3nLiG1Q4qfBhBbNVuPOQOFFz7fQZ6Qea\nIP3e\r\n=ldly\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC/pfzR0kO92ILOBkltRA9BAMQynTnBx0ckhFPs1okXLgIgI/3JJ7Mc9Le8hduJNzDQrPQ1cR70HoK5o3G68MRcN1I="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.4.0-alpha.0_1624842781548_0.04294045738548502"},"_hasShrinkwrap":false},"2.4.0-alpha.1":{"name":"@giraphql/plugin-scope-auth","version":"2.4.0-alpha.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.9.0-alpha.1","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"042e0b1b98acbe84f4761f028eefd25d178bf736","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.4.0-alpha.1","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-F7y43V+7MGhTMbgRlaqBxNYnuXHghFarMbgqdMinH4O9ILcq2UTGPBIQ0yDX7JbHxo5/NvtFfuCsz5vYXAkiqg==","shasum":"0e41670d9ee09c256c0202de887fef152471db4d","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.4.0-alpha.1.tgz","fileCount":100,"unpackedSize":447169,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg2hFzCRA9TVsSAnZWagAAURAP/RljXnWAJENk5Dv7FoNT\nHPk7eKRvpEVDZSuVmRNdtX/zqW9OZf6hD9SCuJCr/DLvgbpsuSlSI6lDdovp\nhr87tZ5yqrTqkoxLaE0ngu/7U7sPy/VfE+VeyhqLs3mt9l8XOCWTX3cZOld4\nECYMzD0PikKqcY3QhrtYVDZ5BCnFeMBCbdHcWTpRNrn6JUei4idZjfbCKqLb\nfyBNWhwnCsbI+EsO7EhkOnYis7e1aLE+F/ljEUZlW6oEeeNZtvLELO1pHZq7\nfXCuou0xbh2dMB+LCf4NGRCXlf8awpbck9Ij6RBt7Pvj9LtUX2maJcxHTXZL\nlbbxHrsp/HVoFcV5w8Ix/47jyl5NDzcWzzOwc+by+L3W4P7XfQvEzIu6zwSJ\nN+/QN9XORkkQ5rYwOJ9tWzMGSNwZccQh4ZN/RvQ0mJuTy0l4Nfhwypek50R9\n+R81adF4vppR8c3Q0Qza0iGBMg94C/qEkfgar7loOd5mxb0TgT1VK+ONaygr\nLHn90+h3pRJCFXNMxf6w5L8ZIpt8okCyCMkT/hdzy6Tv74J+MdSj3uSzPEf0\nnAM3s/1ZwMv3UuM6UewgyDLTa2GFJ3kYiU4p2J3BlXsnRECAnRgDjr+Zy8Ss\nLsb80wqTsEvXW4NmENg/fhQaYVRXi7IoGgiYd2BtkdYX4K+Hm4OrXU1cNDMw\nNhgL\r\n=fRzr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDq1MfJ7McdwGp+IVLHv66Ib6SNceGS9moket7lj9I2dAIhAOaYCcG97NhepR/28f8u+TnNKptQJQuKk0m2ji60e7tM"}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.4.0-alpha.1_1624904051400_0.266914864504584"},"_hasShrinkwrap":false},"2.4.0":{"name":"@giraphql/plugin-scope-auth","version":"2.4.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.9.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"2b03d2b65225d9c6662e41aa859729343ea24c78","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.4.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-bT2RisXcEYrdVU/FTEBtqATgd+xT4xuvTEzGN4hgW4QHbsEQusZiQyKHtlLy6a91YKnSTd6qojMjY735Osi17A==","shasum":"fa100e79be144d152ce2e966266793927f1b58d7","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.4.0.tgz","fileCount":100,"unpackedSize":447250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg2hTVCRA9TVsSAnZWagAAlvsP/0zpGmadZWFG7QKVo4QY\nbIZdTEggQlguXsztQvtcOm5qHJTVZBV4PpC9yyaRTr9iP3wyKg84GSOn94PF\nRGJ8aoKT9s5lO9dVZyl6qdho0j68uPcCjL+/J7SI7NCcWBNhzB2ZfxTYqiOx\nkkIKujDTZYJC9FGLggcfFsrEMWLn182gjsD/PYJKdFj6kGH56RBgEPfo9V0A\nBWjGGSblXYdxsb19YvMR2b3IDtWeMN2boCPMVT37wYjkeH3dovrnU4S2MBXp\nykNTTiST3q4GoZssWwPOyz7f+BicU+yMbeimLocaEyFgcItnXa9iqw7Vz01v\nd/6rGj3K71aQ36DQ3E6qUxW/Eo7Z8hl1E/Sx8lXWSOPaZsf3igWTEytCX36Q\n2rtVW+hgiz0Tp8RGIK/ruKmath4Ib7pO/eq6u3JqRtO9vc08f8GacEi4s/x9\nrIsx2es3C8Y8P1TW2naIt5J2iWC+D9QgGedf6FOcH9HPYT6S498MsFLlJooq\niFF3pDqb9HAt08ip9DJ41I/wu1kM0vPAWwaNv7H3tEufECpSTeLOCZMmrQXu\nhEy8S8qtpq8SZjSiHdKeyWNppP0/GSnhom//uVI0u0crZn2tdGbB4TJNKllS\n3WOBjiuvjbgKx0osLTnF1C1PpofN27EaMEfNgGdklJjK7GSoAaAmjw7ENzYd\n31a/\r\n=bE6E\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFsZPD/JLUPfeokitTTFaPfl0FkCzyEe6pZkD8LdIhJxAiA9M9LVdOOdPM6T4aWsnxXHVvoWYZjDYp45r3x4lzsCPw=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.4.0_1624904916598_0.9380870675051423"},"_hasShrinkwrap":false},"2.4.1":{"name":"@giraphql/plugin-scope-auth","version":"2.4.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.9.1","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"1b71ada86ca1fc5b2cedd4cc24a6433ca19ecc54","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.4.1","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-HhEpZKhmv4g0mYB/E/HpmN3Jw+8vRXBHzHeo0n3mxLpJH6CWtynHckFicEWRzmKtsUxRTSC7Od0aceEtVvFf/A==","shasum":"d2b0d8ae9ba52e2742bfd738836c8801511b37c1","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.4.1.tgz","fileCount":100,"unpackedSize":447347,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg33JXCRA9TVsSAnZWagAA9IMQAJGuwZyTwv5Lu7idnLa+\nngpvPsgLqwqlgwk30GLsJBzzpkDphtJl8nbp4Bgkj0AQj0hpF2Rz/d2Sbkr+\nLFrgCkPXRuOdr62tBqWEoc3hbUm3o4jlb9P26Xa7BNIZNdmIl7p94HqFdpsw\noM+dwaa0wxyz4M1wgb7niqhMf6EnhXuyJCg/X3gYbexAQojIW+RTCgOUgYMR\nJx+TxINMWtrfnYfTQjGS0OtUgsTsjmkE7iN4f1u3T7STzfbs9ajWec4HGnYo\nVvz5J2LyyycewAJj38U7KlACUuxrMAqINWtuIGHFezP7sPtIPVyG8jRKSEe5\nqI4JUjr/AqHo4X4Z4B+igrZkhRVdXGLJy+rigXDorFSrVi+fWhO+9Ed/7All\n4KeFzpR0iQLmYRUKfnLXcDsPHsJhPWF7E6MCW5YW92bC2dwYzK9+ZbK988wY\nS0GNTz1f4SnbIXwpWEikGUQM1rXPkQnj6nShAWZR+MbndeBnf96ihGhY93Sn\nudMX+dSL1iHrwGKFNPf0YWjdzlBLIZH9f/Qed1aRakhgV8ju7KOBfc4b66qm\nvOjW8AB7Cy/3vtM3RAEEzIw+RFkt0jLa3Yo22fCzvuti03hXr6oERFr99pqj\nIMNV0xU3cnj5RmHv+8HL+k3AiX5EZb/jAqsi5219n1xMXztd4zOR+F85gG4v\nCFuX\r\n=iFLz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFzrSi/XifIDUzIV2Yi7s1vUcjpVUcY8oWnXmCbfr2PwAiAC5+wOBxSbEKM2g/CIDqWS6rFn+Zg4JcFD8aQJUOT31g=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.4.1_1625256535426_0.25737202576715323"},"_hasShrinkwrap":false},"2.5.0-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.5.0-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.10.0-alpha.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"f04bb0d741042985bd6fb8a5659b7c72b297979c","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.5.0-alpha.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-wj9legl9HdmSdWEbQsLwp9ZJ8t8sMGE0WJ84l1I/dILDK7AnvCM+BeLBp7bmd9tFvNhht0pdU9RH5T/Rw4uj9g==","shasum":"85c720a968c5d74b645c09b47e54a2786be2c0b6","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.5.0-alpha.0.tgz","fileCount":100,"unpackedSize":287662,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg4SvTCRA9TVsSAnZWagAATdIP/jHQ74585RnhoTQGuXEX\nXJEuR+tFafH++BUkBDYhuy9BLlbng8qaJo3s45a/nLzZlB8DKz9ZsTu8aGhg\nm/IHZZBIzOAIqfCLQA5F+2ZbOuFHuxks1H5jTZCl8Zywgfcx7vzj55SbT1rs\nW2LovjqfH+5BOvcluP3b1CLYY3Fg2WVWnhc2wTN/5C9ZL74qO9wgFZYEXHbA\ngeq4Fw8bA21ypSHcEirCDxTA7JUaOXCCyrzEkvReyHcQOzCa/vwNrWF/pjeW\n0qKbk3uXuXyQ3gGCtQU3hKg3hh+wW+Pe3GOtyAb2g7fx2m+ovJkjWiZ66Dw/\nWnSB6BF7styDP4hsa7Rd0k27N3pHgTnxwDHF4OEtt9CMrjoICC35LVp6jOWx\nzpehmZKUef8T5EPS0mSePlg1VRcNvdZau9QtShzWeLeNFioVeQovIhWzYmZ8\nICyOoRgIvkq1hHTX2jSEcVxDBG4w3LULdP/h+WJ76vD0JkPzWuvMmNEoQ6/M\nGnTgyqX2llYjhIyhisQW4oADjBF0JFamxxRBZ9Aq9pl6RpxFeJQRawpPGwDs\nEZshaoDTR1X+7yk9LxIlQ1kJibZyuOljRQwkgiYP9st9K+j9N5VcRP7udaYy\nMyOrofxueEuDwGzcOH7Ecg9/8olQWB4PXWfvBykCmScJcpTyWsKxMEIdbnbK\nV4RG\r\n=zgId\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEQwGXjmkY9UyIM6MLHG6lhg7v14b1QcWpdREQWcZsC9AiBnl5zamxD43bVKIH1LCp7NrKhB05FnN8CoCiCmNeSMTw=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.5.0-alpha.0_1625369548165_0.19459535905518566"},"_hasShrinkwrap":false},"2.5.0":{"name":"@giraphql/plugin-scope-auth","version":"2.5.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.10.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.5.0","_nodeVersion":"15.14.0","_npmVersion":"lerna/4.0.0/node@v15.14.0+x64 (darwin)","dist":{"integrity":"sha512-adY3gTBT4UF/3lWIyw9UFde5GnS6MsMj2/AMOxQd5S7zmasDnpAuYJlTFBJr2n1SUo+DhFXMpYFXnhZAlIkodQ==","shasum":"3b7ffc56175e6d3ffca468394a28e536952ca3f4","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.5.0.tgz","fileCount":100,"unpackedSize":287743,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg4TaPCRA9TVsSAnZWagAAM0YP+QCaT7O4fD8LwaeTs3u2\nq3ra4liAijVn/HTdSuhsHNsAa4EIXTPjt+BZlx0sYZUDF0Y3K0T+VjDgl6u8\n+60Sq4UeB7o2HwFYUqWPf3M1hr77J8g7EDETenZQPnLDEyhCzCJFfLZZtgkd\n1W300E7h8LolIpjTOUTgLqk6J+DgL0SXuxyMhjwq59DGpYiQ9LgQZxJx9vrO\nzfXgSbyqzXKft/g32GWPN6Uou91g0WQaDI+wsW4BKax1oRbCNxHZ81n6yDOZ\nFxa71Xo91Mmgdq39J6dPAGYu8qRVwDx4EwU0JoRRLFKTejYjHvuxA6XJxF/S\nnknbJ9P6WSVcAFs6Afv1sg3yFLHVrXgYQzixfwaWTIh+Z2DgOU9gXMOqsQq0\n50EIMcIHD1YGUl4HS2IBLzTC5p33/RHehhYX8wjWNqgx0ZhChcVPpDYIl1+Y\n63x7wvhX5KVmcMFfnNDa4T9vx0lEpvq1w62pPaEnSADRj0vSDNlJ6WSSlDJc\nnqOZLqixz4HLWsSvjUksN/vjZMxVXfbBKsEuDpTduzc1t92Pa0ewRMJQngcZ\nIpKZBSDaxt9N/lLbwrFrNESqueZXzP21VYx0goLOcfC4ruzs0mC0YY4fRrbx\nH3gOWoYVihCZXwIfbFBQ/28nsjRLrNsYZbdzdyi5GWlaPj5ZdqytLCMVQOOU\nYgb2\r\n=O0fr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB6M0SL6H36rslW6iexF3ep7B+5mb0rzicX7hN1LmT9uAiEA6M5i070hX6Angu7fsRTFBqodKsqnV40/QkNeS1QjMKs="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.5.0_1625372302775_0.25882098934596787"},"_hasShrinkwrap":false},"2.5.1":{"name":"@giraphql/plugin-scope-auth","version":"2.5.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.10.1","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"15509521ab5b20ba1a0cdaf5ae17e21c307f288a","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.5.1","_nodeVersion":"12.22.3","_npmVersion":"lerna/4.0.0/node@v12.22.3+x64 (darwin)","dist":{"integrity":"sha512-oJrxOVDMx5b44wS1eb6m1SShcJr03+fe9yg6mZxv+L8TTwUyHmhQrWWBfizWETfiEi4Mu/pum5XafFOsscEMXg==","shasum":"71ac33ad2c39cb38e7199765e00ba14a66d9943a","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.5.1.tgz","fileCount":100,"unpackedSize":287840,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg6Rd1CRA9TVsSAnZWagAA3ecQAKD6q28aX9B0adhsfGbX\nZnIFb5cW6fyqWvA0wWAJGHfqfLjUNOfLLqDq1n31DnQs0wZw2uwUfmYSRt9w\nKjf168mndUNoEAUeLE3P8oFjhFAvAXB7uZpkqIEJw/F1brS62SIdiPpU0AxF\nCLzJZMY8Z+YRLboLEkhDa2vnqh4NOsaLalC+fxsktiw3g77nWECVfGf0bbDY\noxyYn+QgSIhPuKt/Ub4B0Uak0QisRxl8POs8pvW4PwMhU9Eu4dIMpbZtYLE2\nVTTPjkUQ39CnnBOYDO2HEtcp1NgbzdbHQbCR/r1ZeXx9gamyKltZ8DI85/zG\npN/HOkc8cVlO9rcWd7vUJlUvXPULl7qBrcjbxl07FMeWYED9ef390ZoVzu+M\nyABFcPrIU1dgQQL9fvJbcMsOMbiqmcKp99EvcM6GlLqtwqxUbswmEGte9JVY\nLzbbeoNaGJKexHFMn/e9emdcOBHu+Ud/09QQIa5UTyeaWNIvyuMasN2cpDe0\nWKgYwum87URWXAKqzisVqzkoxBzyCbp9//uCurLe/In/aue4b+Uwg1AjMd+m\nne+Q7h2CKXTxGWlk8/mbyInyUZX2Gf1/d0oF9gta/By2uTFmXjkO0IcprZTY\nlwtr8yH2w7whDQ93Vi/SEF8llSX1Q4yqOoXFQ80DXy7VhR8xaqF1JF9k6IV4\nExFk\r\n=3/AT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxhk2ELts3NjzjKHNMpEhTw+pz3bB1IjL79RAps3LtHQIgZv6enCKM9YXMBfUs8vNQtExeQOSEy8u/TzOKrj0aEY8="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.5.1_1625888628664_0.4191986572242896"},"_hasShrinkwrap":false},"2.6.0-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.6.0-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.10.2-alpha.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"b42fce4efd2c4567c08615ab58f3dcd4a756f745","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.6.0-alpha.0","_nodeVersion":"14.17.3","_npmVersion":"lerna/4.0.0/node@v14.17.3+x64 (darwin)","dist":{"integrity":"sha512-LST0JJxQL6aG2DDXAe720f7yfZ8qVFQIrvvLjPBHmineAgOA5DSHp2BX15Ko+lLdkUU0/aq8Si2o1qh/BQLTaw==","shasum":"23ad4416e05f2908b7c839e0200c16a3b9b2deb9","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.6.0-alpha.0.tgz","fileCount":100,"unpackedSize":295898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8lOZCRA9TVsSAnZWagAApWUP/jp8oY1I4iw5CwA411bf\nSmGdPD9ir+TsbZYd9DtpIJuAdgpUjNMNYO5vAAe5zp49Nyq5fIvH8PFrH5Hj\ntCn2eiOv1yyWxY1SSZoBdfS79BMxWTtXgqO4Gl/dqCVg67fsTYJbs9iaAVgw\nxjgdrGvJhC2vdGHRTvNOZdqNoH6DPsb3ct1t7LYUTcCt1BD4kopht+ES4d8X\ntGqR5Ca2YUQdEEJMnD7yVhkLOLXT0Q2P9LMWndCDkBmLhy2UqkZS3hwEb2+i\nfYk/zZJtu2D7zmYpcsL2ond9V52lFG+d9H4zsgd2MSjg80GyiiPdE/kIgOdt\n/PO3CtRe6Wtjb+iA7hfwREzB5DKH3ylxJdk8x7jhBFnhKheg6k6Bj81LPsYV\nKABykbpX48CUgqK+24xArMWroNO3rOzVJkmnrBmHR9ZVcj17085vk6EFt5TJ\nGD4nDjq6AGW6RqeR2prG/G+l9xwcGkBoZZeIrukLtiQiCDx8rNhMZ9KJPrMY\n8/Lnf59TM1Ij9S1Z7O55Fu2DvpimO46HG3kqZB4S4u46/jUWVstyBCtQ/ZgU\nLgQ9iLD+RN6Y9ROnC+EG07+bx4HwPkEhfgbpYBW9Y2bdm/1K4ek0Gm+GGTvE\niDIppy9rpmYNc5G+iLW0x2n1owroieavWp3N68EFV0Bm292UWeFQ4MFwI2Gd\nBZYy\r\n=rP61\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyGFmNK69xYg9sykbmIuwC0IDxShk2+Z4YzHD6oxOgegIgGr61TckPL28NiGZrJUGIRwNt5aJestj8NDlN13VA3f0="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.6.0-alpha.0_1626493849558_0.37613835112052807"},"_hasShrinkwrap":false},"2.6.0":{"name":"@giraphql/plugin-scope-auth","version":"2.6.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.10.2","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"fbab24dd5a3d379ac992bce22773f40196c1fdb5","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.6.0","_nodeVersion":"14.17.3","_npmVersion":"lerna/4.0.0/node@v14.17.3+x64 (darwin)","dist":{"integrity":"sha512-/P8MOrLBPwV8F9dh5tf4ND1di/v13lK+R4+UyM9dy3takzTGVakcJxfRYTuXKNVEtC/KfsiPvMDZwFUjg9v0Kw==","shasum":"7515810aa846c8e4227a59ee0547b409dcbc9d9c","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.6.0.tgz","fileCount":100,"unpackedSize":295979,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+w10CRA9TVsSAnZWagAAX94P+QB2foKBSSK8ZYNZJ4kX\nWymoX4e4m9BHWuO9M+ys6NM80OfMk7mlhWsb+JoxH8q9HqQDrLmqlVQzo61P\nKGJAAzGL51QtNNR6K7lN3pZczOIloY3vcp51cijDEYBa/6/9BPa3ZnDbIA1r\ngNp3Yd110frUJTpu4H1Q4QNJkHurld+bfbXt2593gGLs6Dy1SV+J8COTOFMp\n47iwe8/fZstvcBlD0BofzyIY/jUWiPC/a2w7jWup213jqHV8bT/EV55wYmzM\n6gXAq2FLtm/bq4tfikFqk7KwUoJDN6IoU0ASOfPBeJXi6d2+m1xm52JnMyb1\nkWj93NKVFL7Alu3TLjkGf6tUjlXsskIi5bc8EnYpyVl4htRyUl/90qQq0TlV\noeFzszQS/4gXVuNYaltC0L6pkDd4Tq/esRf/34YBjOGK7IamGR/g1+Eug8Dc\n25DdnUgNrFMNcbtiqKK9ZhOxjxLyQurUZ7eEf6OUzaujNsUA5QUjh1RJRPgE\nMstHK6rblHQE/VMXCeCJ+m7HJS9rw4TmFf16PcwFK96wrg5cS4pVCudv+Pnx\npvdiMQrra7FN/k3kG3+1S+gR1tXCtcQAtj3QCKmicqifzZqyibhJOL6wvoOU\nW72L9EW1yYrJCrKvGv1VwDmaZCqhU6vdBkC6NTPJEjnXUTjW6hjkvwykAu3+\nc0q4\r\n=BuiS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDgxo6BuS+Ecm7CDs9PMEGE7QxDT6f6E0mXLbAxGmhxTwIgJBirYolh0/8wGiIQNF4v97cBz5Fxot6Mw/OiuRkw0zs="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.6.0_1627065716056_0.22935980643567322"},"_hasShrinkwrap":false},"2.7.0":{"name":"@giraphql/plugin-scope-auth","version":"2.7.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.11.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"220b996dbac73ebc4de820931bbe8dff60c7cad9","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.7.0","_nodeVersion":"14.17.3","_npmVersion":"lerna/4.0.0/node@v14.17.3+x64 (darwin)","dist":{"integrity":"sha512-p6U/T1WvvtOtO84G0RoxKyIu5qMX/FJLUOH8hLKy8KMe2fOlttrLRio2MR6dxhWVMPGteIr+scJped8/uYhi0w==","shasum":"25ed2d9c997f60fcf1396ff4bff2cab0aedc1354","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.7.0.tgz","fileCount":87,"unpackedSize":210060,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhBIs3CRA9TVsSAnZWagAAvXcP+wTfZYmsZR54CeX2mexI\nwVUbMsfIdPT2MxFiIakOzR2G5kosc9NRx8UrARYljDQv2RWa/Cb9VBigSjtV\nfcA0p7s2Zr/BQsMlNwvwNx+F1gPjWUEvb2MNwmCjDFUZx2tjQpknXr4vA/a8\nic2wP4ORcQmV1bqL9sp8p+/38MLvUOSxk212J0v6IECbciyqY+EkShWtitjD\nDbI6NBJQlJ1wHk9PYjua2kbyN7A+qfrXePZ2Wsn7DXoA+ALlZtcl3m0k/hQ8\nvI72I9xIYK6AyKDYA4Pd0/qMoThxM5uvRv32aeanyQ5cuFihyDCwqkRYllU+\n4iuNC6k0KVNKoGJsF2vTgdYxMS3cgexgVwAcvytM0TjKtcajAF30gmwmJoji\nll7cFXDej8RQqWU8LsyTsp48GaVayijl85PXTwgujcEhghe/DWL+qaoArj1N\nEqjR0jBFdXDqwCdJJuI7d3ejomKtZnX7fxAr1Lkpp/Q3Mj0DKWVgEzpmwJRf\nc2Ak0xf2sN8x1lN5oe5pX7jLduaZskg0BcDqR3IlaiZCR5sfgs6W2Ihcorb9\nJe+pIJMrAobu3tbAZIjogRaAWQATLsUt4VPAirW6J6UmK9XWRHQzFEgF8VrO\nlr7kksT5znqfig2e18tnlCLpoSNoT8vvA+raWSJNw1xCnzVmQplRxq5WwzDF\n4Hmn\r\n=V597\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCKVYafuKOjjj3cUE/3zSkpe+/rxWApo5q97Tgy8oINwgIgdc8fL7H56Mt7VGfd1DNr0nj0fIfrva4nmgULNWtsLV4="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.7.0_1627687735404_0.5866158289350432"},"_hasShrinkwrap":false},"2.7.1-alpha.0":{"name":"@giraphql/plugin-scope-auth","version":"2.7.1-alpha.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.12.0-alpha.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9f586f4146acf7841706aba3ce84826d6e4f7cdf","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.7.1-alpha.0","_nodeVersion":"14.17.3","_npmVersion":"lerna/4.0.0/node@v14.17.3+x64 (darwin)","dist":{"integrity":"sha512-IlQz0HNkDhJNMhGWYIHwWxf8eFqfvda6VL+rlVff2SQZNsivhL8lA5znveiW5pOpOi1rwIXPbWFRb8KDhoxqyw==","shasum":"158bb125a1378f7e47b8472411f73ca8e582132b","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.7.1-alpha.0.tgz","fileCount":87,"unpackedSize":210185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhB314CRA9TVsSAnZWagAAl0EP/2z4LGet/PQPi9jt5wRz\nTV+38yOoSKp1tsOszXdqws13xwl5WT5ZyvvCMBh3I/JwGj1P1G0s2e64AT1V\neU0FcVsen+RVhdadfYKt74YPrimWpGFzsAogq/3qBHVaYTtN0jxqetGaB3nn\n8+xCt/72JFln4ve6q33ogH2sIxsCoXdwY9719G/rgntnEZl5QdLAYm+j2B+F\naMorEvZTNUogMmmfbG9IdFBuM1Nygy84LRlYDL0NYTtSjz4rrvVsTzST30Z/\nGYzexq3MBhYabYUVplRee4X8eqxSdlmqyTO9E4RNvWVUpwTuVEwSh8bR6vRe\nFj+Bzr9JJZX88CtAytP0fmrsHCbVxz50pgS648ZvTx+kbG0KjJokzhCIpinm\naJLgJxYGte93LgqxARq1K8uGpYjBLcCBUqdzYBa6vmSwckbABDB1CkDnzGd1\nGrsWGRNaPzIhCUM3JVXcwCQiiQULU7+P+6VJFRk8NFppZ6pdwZO6ZMLAaW2P\nk+sz4d50luitpwHFpturle8Z4azY3HJqKvjvAVhd/5B4amttNo02LHxv5UnA\nDzMd9sYANGyaFN0GsvAs73eiIyLCL+Ref1UXyiW8PtK+ID3kjmloPNMrzMb8\n2Hrpw2M/e7xBnRckItuD47tcbY/gscdEb42Qpv7f2+ZG9Hr3lLtGy4pC5SOw\nSa1i\r\n=x95K\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCaR4p9+XVpKSS9axGuCUvEA75ASrSJRu0CUbfs2GCpcAIhAIC5SAJMBd5jQdVS2JfTQkYFvcDGRxjwzXzeyXCppHKi"}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.7.1-alpha.0_1627880823910_0.3899123950628487"},"_hasShrinkwrap":false},"2.7.1":{"name":"@giraphql/plugin-scope-auth","version":"2.7.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.12.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"c28e5daa0ddb0e240b97113013790586e858f49f","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.7.1","_nodeVersion":"14.17.3","_npmVersion":"lerna/4.0.0/node@v14.17.3+x64 (darwin)","dist":{"integrity":"sha512-T03X9QHYnq2FNN/klVWbQ+odzjGhNdwTy3ihlQNU9UAXadXAnhRe2fYX0niE6R3baVoY5QSgXsNb7G7tMnAkGw==","shasum":"c8ce5cf392607da136192b8040e685679373910e","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.7.1.tgz","fileCount":87,"unpackedSize":210420,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhCMA1CRA9TVsSAnZWagAA2J0P/i8wFtkKPbMTD+VlKHQt\n4v+JXITz6y8YRYsIbwlMC7pgMRv0RWcsF+qTizP4/bU53tpSfaJ/5Re7q/qu\nqlDehtzf0FP03mXiHPJbT4NqxkuiR3h4vrr8VgPBSkRfcaNNXAuZMnVtxN95\nDyhq7NmaY8IKTMB6Tvh5GoTXXatjUFVgAmaOlNJZNhWYWmk5mkvL8ss10xFC\ntxKmtUtAZLLw8MXPF1yLrPMI4U0FlsUwFRXgDESIBcU1jE1bDVoXYOgiXv6/\n9rr9wAv7BE0Ig2DUUbc4KztPBAT/eqGvcunBG3YvFM8dX8AGyf3RbcDBmejG\n9cBODPa9Suong6z0esxZ83e/PDH7WpapZeHk6uxs26MOebH3hScaEFedMOaU\nSn+1X9Cy/Lu5vx1CZpiYixqtE7qJggu5km2ipY/hcBS3Lq4r+qWY1bgeGiO/\nSbgQfJM76D2tzEXChI2/J8ZSJo5cFYQNDrfPB7PMxy09ZvL9dvdrDmaAL2kh\nGGYCuih23FJZfycB+Yjbq7qXJEo6e1evotVi72ux8fkON1fCNQKHE7hM2o4g\n1GGYb8Z8c6ujhPg6m/TPbx2QzQcG0uwMfsrGFHTV9beTBr7dNo+XuA3aIH8s\nXWbyiOKX+4s5Yj1O0wwmfcNI41ZVLcmyC9pbEfGeO1N3d7GAuEIvwD2+2f9k\nhg2p\r\n=GzYs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDrAtrlvv8G+HtSKCpjqOtl1pxanfer/hAvHCQmL/0VlwIgHy7JmYa+CcqySsU1wUWQ4q0X5qBnvF5bDWV7E7jkY4k="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.7.1_1627963445808_0.5192352208446915"},"_hasShrinkwrap":false},"2.8.0":{"name":"@giraphql/plugin-scope-auth","version":"2.8.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.13.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.8.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.8.0","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-T8hZW3++AWkucTqRYvofmHpnKvMQ8gmrf/tSgIYkPCcy4PQDEdQZrAc/P2gkcJ2hmklmg4QN3uv9cuuq9Z+TAQ==","shasum":"f1945c90ffe748aec55caeb8e0d3eb3eabcb92dd","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.8.0.tgz","fileCount":14,"unpackedSize":52585,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhC5AQCRA9TVsSAnZWagAAeoUP/js0L3GwSF8iUAhHJj0e\nj2yQ+5jEbspWNCdcbDO2aHyqPJkuElorBk3ePWDkHR6ss3CPRt6lYl3Wcv7g\n9srhmyWg8NHUlUJdUqfVuqTZMIehMfjUHsvV+eHEzPDwi8n+fhM220cI6DPO\nUuEoZaJi47uFjZdtWnk5O/sixJl6UMtoj3Mpwt52SaQ1Hr9QfOBW2hiZOMT8\n9RATSdIYu6+24USueLH77MYW1gG2DARq2YSArm+Cv2ovCdBwwLGvwoYmqLgk\nfY/ekxDwHtGmkr1G6q6YpjsLu6HmR2tsvUj7C/26QMgTquhYC4BKqxqmUjOO\n7QJcpUYNFDr0VZANyI7z9XUuAdenntD+RgRSlAy0bpHDpmpUPnPtBAL7wbKu\nsBxJCxY39kBVM48sg0o/GRetL2jcvSaPZcFKnvuvXlC1fYstzrCiPauVeElw\n/VZOsYLT79B+uX3wQuG0NIXgKNtNxjhslu3apahC74j9U+YDcDMOqHBYbVnZ\nQpbj9mOADcVXkaOEujr/xiU3FEhs2u/VRrTVq1O6sT0eNdNt2ASIPOMHhMiT\n/eHNBj7K8az47yy6NDxbeeJ4W2p9k7sxKwZ11YdBnSlCbGEvuHAPgGRyIE1D\negIl56OCZYKE+l+C02xRe/F2l2UQ5KMyeks/mbhfNcVZHIq4kVuUEDfEkypm\nloYd\r\n=irLG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHHn6k7+D/jhyeMl0IQ4bDrJAyv+7FAnw9Ia4Udxm1dHAiEA+m24s6pJsLjlmGOjK7RzgmypqQQq10zY1NYq1W2WT5g="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.8.0_1628147728359_0.807342069422156"},"_hasShrinkwrap":false},"2.8.1":{"name":"@giraphql/plugin-scope-auth","version":"2.8.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.13.1","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.8.1.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.8.1","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-mKK7unW9WRqAK3qED2O/s/O22Ti5RpeCTvmaG8XMy4jrMq2g8SFQz4WAcpG3PQz8NlHsjk7iddR5KacAd4ciEQ==","shasum":"f6aa5d7a1b29f66be04a0404881282e28a9096ae","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.8.1.tgz","fileCount":87,"unpackedSize":222063,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhC5GyCRA9TVsSAnZWagAA9YkQAKTfGkp05PaYlv1ULMB6\n4xeZJLktZ8djatXaTYfYTHa3zLTlN1MmUXAy5w4UdP/7IGDLcuvzXbAShixI\nGkMm0uiKRqw9VfHNb6H1+zt5mXmQ2saD6dhniOJNEcrarkuF2CDb9kS0u2wE\nSU6q4RHx9rOd3kujOho4JjtJi0aqjGz4w0XvEEB3BX5nsyqzyEIyev7piHX7\n0X+J0i628qByQFfdcijKP4g7e3eyNhiYviJJvflohlJ8XhHq6GrztV8A863T\njiBaG0SFq+ihUzNwkNCnwHDpTU+mADLgIfvC/kkB9zlQsfn+zXKbH4qF5pZW\nyXIKYTzN/eekTtwtetIyxeX1V7qwvVor819DiUlJ/3ZMPT39WzNRfFyv0XnH\nsGBgNKSPfNudVdCpbUmsHaCbYIGKY4AId5X4+K1o0V4RsRIZIdOa/fnmZzPK\n/EJWbYVA8puXE3oW3n2pFk/G+R5THJCunx7Tga7y4zsOMvC5Vub4Zp1DUsoW\n+ykoz804p7TBbTRqJG2oXst9PbdhI/ZzjARE0nNEGgiJzyJZ8YdLcnkTPui/\nyq3AeM6+aHpSUrwCRCbnHnBx95ynbruj6aHejzMuqgidAfCJKB6OMBlmPNgE\nOUQldXkCFscuZbIKVc8MOiISd64eKHZKFd3DwrKjNsYSbyqng4bJGrxlel7r\n3CqH\r\n=1kH0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA/3JISbozJ5blraqj5NxeltDkZgSxANbwv4mR13hITNAiEAtbKdK5LvR+A8gY95xW/y6dYNFQvQ/N/ZA/3xPvsO/+U="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.8.1_1628148146143_0.7745722702535514"},"_hasShrinkwrap":false},"0.0.0-preview-202177065":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-202177065","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-202177065","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-202177065.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-202177065","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-45y7GeU1EcziR10gmNph+DKksrX51w2cL/GXrPUYJoMEjeR/HU7joeJj0mHA0SvdBD7L6Ciu7CvsCXrRVO2rsA==","shasum":"4555b4a74914851f2db5aef7a9e075ec2659a9d3","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-202177065.tgz","fileCount":87,"unpackedSize":222700,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDc6qCRA9TVsSAnZWagAAEBwP/3TjWEI8bNmB3Bn0bKgz\n3iaESzRcgioOX8tYNCiR6FkuEz13Cj2CXtiWd6U1BjaCu3wSWEuS6MoH94mv\nHiDFkxnnNEB8H2Kpr1QatswaPatwI1o4hIP+iiPge0TyBeeUSR6HRYUMKPqI\n70KrmhkknFg2WlYdu//WTKB8jN2hWvX5xYxYvV0JdOhCt+TaKCaVP4B1tZ5d\nWNsON1cMoNrBOOuJy59bMkDUsiTAo85rqM5kTlCAoePBaVjhuLO0sYQCCyrz\nBTnLFxbHgc3pogBMyh5U4rB6Q0fF2BEDM4igW8OlzMuOnEbj4SVlHm2XO+EN\nd+DpxZu2p7MLiRRjwLN/kFuPVbnMum9zH5c6qG7lYG3qwpxK/wP2BhD94602\n/y5fMJox4XhDulkcNUwkKKXOSoYAiyc/GIuTGZsswRp77jrJuxJaKIgI2cB8\nMrySotjHN8l1WUnRwMfmRKMDeN0hzgssQns1ziL2oC+/2aBDZDcHo8B6MU0v\nVCUZ14V9CssQeOxP2x6c16xrBGLglXZfSN21nB7A/G473Iv9K6Xs0WRMbfGp\nrb1WV120cibWkORSWnhCF6PvAbmepQd4habbKgcGhyMmSBvAvXLcrX2GhG7i\nL/guO+cEWf1/PpaFrEnFMQ8NiGweHBQBzg55x9BYwwqvQQPOkgCVQG1LosU2\njjBY\r\n=vLsH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBi/Dq0PyORSx3xrvQaG2pdG2QPiej564S/fn0tlQWwAAiBWn5li3Pq2zOT7p8FyiFOJk6DYb5ofpZEGD9JcvD+OmA=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-202177065_1628294826533_0.00882348166543201"},"_hasShrinkwrap":false},"0.0.0-preview-20217701452":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-20217701452","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-20217701452","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-20217701452.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-20217701452","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-SmhGEU4hUzzLDxciuIkvsPZ9t2TfSNXGRPj5mvBWO3nsaNAPCVXbBhV5cLTJBdP9xVL5UnAw80Y6zoX6afwU8Q==","shasum":"8e1a2c54dcef53fff9c74d8df574c6aa4b1fc919","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-20217701452.tgz","fileCount":87,"unpackedSize":222706,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDdCOCRA9TVsSAnZWagAARcUP/2SMcNRCLZYjVMcgxn+3\nvYR2D1HSYFRCTqxYlLpTtEkXrarL3mPzcugEY9WzZWtQsND1mUye9P+Jxl0d\negbcpGtJSc/nK9TFmnZKpRbqETqYHjMOsiOifZqrbs7VCvdPUMh4c6I3gZq8\nCIiIQy+rElqCkI7tp47Q1HPqzEe/VEH4FW0Hbw4cNMi0lI4/VfGYvKxqBcf2\nW6X0Y70JF9SW6Vsl+/vZLFfMxpbl3yyfEjHQdrGF1fbDkDQrD+b+9Ug7heJZ\nsBeA8rhkUEjh9ms39fZEp0HDpsidNWQGPC5Ni++Wbi9vZJkqOpENdgmvqfFW\nCm9jDEssLmQNYj6/lGMpZ5HhI+CRCFer/s4LwCyEf+yk+omSoD7MUFR+acf8\nt4heX64kfz6O5e0YH4zKFQJVUfiBGbO0PezwhirkMxHpVvYkTAp0jXlWpSET\nmpxWU7dRUW6JLW3qOThhilq+RksCyNHwaZ94B5bTkGlrUnQodc0Em/fZ43by\nv0lgt7+QFvbFl8+G5uA2dUGKJrwH/pDTBRB7m/FD9R8g3UDLzyrePvHzD6UA\njUSnlswhDnicSCYdcADJ4/+RaaUzxyaHmf+KvDOWWcZyHVqmlFIuj5Ks4iJw\nKlIf7Gg4RD0yOXuSDx5r8MnubIRqEFYfEPLAU5tNA6/QOpG0abjq2qWepZ0/\n2V08\r\n=XB2k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGz0XuK4drJ8zPcq0KhS6mtlXpTGVTCAu8bJOclYbPoRAiEAr70yUGBEfWaslDK81y0c1g5tt4PRcAqFftX+I1egiOU="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-20217701452_1628295310702_0.460917391902127"},"_hasShrinkwrap":false},"2.8.2":{"name":"@giraphql/plugin-scope-auth","version":"2.8.2","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.13.2","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.8.2.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.8.2","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-AIvvyJBFY11nlu1YbRKhwpZw6RYBVDWX5RyL5llAGHoEtBTuKtwd/eN2dtR5gM+V1EFYY9roh++DdPr7cr1sqg==","shasum":"839e6e58162040d8b546ac7345cf5e2668a832df","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.8.2.tgz","fileCount":87,"unpackedSize":222127,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDdCnCRA9TVsSAnZWagAAiRUQAIJS+x+Xg50hdZqQhkkf\nxMPJVxy5cDRs/HeVBJx+xUjmC/NvLTj1QdSdgw6m8/q8SxUAhJ8FHaJY8A3K\nIOLDSnTE26QezeP84+Jt6do9laNDPsE485T/DY+8V5RjQU3CRmyt1ZQcDWJL\nGf8OLLC/DaE4h+neNl3fJdkbkkJ6aqtyPzbgjfMIfxAIhatYhtntKiioeiKx\nVPNEQ7YkMdw0V3PJ36D7IjkU6/atlruu6zg75GPmfleqBghe0QNXiWw0MuGE\nmLyIFVOJS56C/IssCMsy6tLmvqhy8M2+ywbki1g/d/UA9QJoimaARlCxucS3\npgFkhuR3Xh+s3euA1RkaKOSn67dwhjduB8rtNWbEVQd2rsqXdMSHrsJG1gLW\nPTSqA4Ogcaf3Ua4p6V+8Eim/4tLO4FNYX9KP0YDUilT2K5tHMDFL8MEEpAQ+\nJQWNUGE5YeuOmZUMf2DdtU79McVZuZVEg2C2IutPvuKZpe7DEbhnnMMsH1To\nkdvT60yy2b4bk/ihR1pw/ISCptYe1WMYjTVNOR4HSbosjolzMECYs7ENgT3Y\nn5VZw1Llvc8ci8KmvAV636oikZS0yUOTYzgL0j8MeqrFN9XjX8Rf3J+n3Doh\nxEUE72H2n9O872Eqc31cFxOz8HEVB7TNZZzvuzKeI2Wwrkn0+jmNzFmys8YG\n2wG/\r\n=4hod\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGf2SBw1zotuxTq+DH0Lrn6Ddf+nry6TJpP0bOG786GoAiBM9E9dlNwfHxlbH29QJbZZP8Jlgu+uLu59v6OG+IAruw=="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.8.2_1628295335402_0.14988242047418288"},"_hasShrinkwrap":false},"0.0.0-preview-20217752147":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-20217752147","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-20217752147","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-20217752147.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-20217752147","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-azCekm5akYqNCr5JciRg+QfSoqVdoW49o+10uuw1ur8EeyBwANTscVYtkJDsWF3YM2m0bTZbzVdHnnXhK6K2+Q==","shasum":"64eb73b5e06f3c000cb5836e93c1684e20911407","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-20217752147.tgz","fileCount":53,"unpackedSize":167727,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDhh9CRA9TVsSAnZWagAA+PUP/2EG2LCmJ3R7D3BHKPZQ\nYkacDWVTwNNyCDUQQBFdu/rlcVPVW1140vq4nZkunNYMVm31u3iMp/T+9qH7\nBFtX6SPNjHR7sS//rWxo27ZirBDg63pOooF484IRhlRcrTaut3pN5/plzDae\nwxpbw8wwaIuarj0VKWNa3QiMfgTFG4cvCIZ/c2FXnNsDItBVVTBIiY24E/Yu\nDL1uI31KacL2K6cxmLeMePl+Ae+ySUNF4hlzIMS9SGI+EyJQbkbxLV2/I4Qx\n07LUt66x0Xqt6rymtKG49Z/+OGy1Z/GCl4b8Srg8ho9105AubBwXrcR3SHJF\nvYN4AjU+Oe1J6aLulvuHmcAruP0iJCrhOypgzz5G/QJDc1W2V8os9oTKhz4S\ns5PbG+4tkSCPiCK88RCIyo/y+lZOzmi5r/tFSVM574JlYDbSm6sDKojobTVC\nM4Jno60xjR/HKgScXB7eJMEmxwJDkE3fMmQCeBJGOHZ54O7hp0iHYAXV/pVV\n6dArnWlmCI4r+0FQfCu0+sjLs1WlVegd+NMi57Fc2/edtIwTfxyhI+7Ua1Oa\nAEKNvt+b9iU5ziAY2Lt0PE+CH9SUCoIdEfAQqQmm3yoUbyoMxTscceQE2aGJ\natMSQ80Td6Oa/kjcq6ZYqMpdzqCJVeJVXMv52qHEdHv2/lnFWgHRFZtcrr86\n5cLE\r\n=Ktth\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDynJlybVTOhHwPl5zEpHoobdzqvUqs5hCqazq+drg8JAIgOrkEH1MZLgvgbgOSEPSdW/bkPF9QQ8RUnSu6jCfIOUU="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-20217752147_1628313724951_0.910558178946342"},"_hasShrinkwrap":false},"0.0.0-preview-20217753333":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-20217753333","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-20217753333","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-20217753333.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-20217753333","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-UmoeMEr53BiavIKnAK+gG8cQZEumd7ZUJVGANFhPrdArMo9EOkjo6XQn7WZY6FVXZvczP4LKCAgHSIz3qy8AEQ==","shasum":"65259e2039db51392d28a3655ed7deb2d53c13b7","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-20217753333.tgz","fileCount":88,"unpackedSize":222729,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDhtACRA9TVsSAnZWagAAfScP/j3b+KPAsle9SoT737lb\nyeh2UdzNHitJ085NdeRsvoPsVF5FtXmfpvrfJvoezjJucza0HuXW53o5fU1u\n8d0OgLnghUvdnXYazSBQLQmNXUNRTKYnjLvAzJLLoNMhel894UeKNfFsvyUl\nRfbvCMFGDx4TpGM2YLnjHB56By3zwTrRE6t6oR/S2HCvx0OicCS8O+/xOeUa\nObAkcawdTXDJ/GM74wPIUJerHUdjUE6IQGqmHjNiAH3QCKtXooFmB//PKA7V\nD9c5v61uCVJ08TpGXiYrgSef72EZzDHeHnUh/GYk4Hs1alfo55q4UlZepVk2\nvRvU9TZI0COvc29odewVWMfSftIbGybI4XTf25aIwQ8Ll7iq9CXwpU/TpbGc\nGPZeupZgRTeegbXhpvaa7fMzXblRJbf6ELqsPDkIYgUlumyMR/5mQbP1Vz8v\n6MJtrkM73sSWE/NpEJ5xZ1h6dza7uGcmnd5hXY3juzaMLOl2W+y8I1kVCxTx\nSi5gO4DR6ML/qOfJOGtwjqUuEY50Qs23jq3LSrBLIR07OC6djNFPYbAzZijh\n3tqBG0TyoyJZGYWgmiMPpO4yTTGVFSW1+IQj67sYtLg9U86uZBMOLNRiiqKG\nbfXaocB8V0amM5Bp09itOCd3JLQt85HvAiorJksqpZqADwqG/5LuEitdhZUy\nUv9H\r\n=3FY0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQv7sL76/xSvOdatneWzkdH1cXgCGNv2sw0hhbVXx4SgIhAITy//jIVHI3lRDUdWK7uSGrrYl6G6EBv5GJI43e9vLJ"}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-20217753333_1628314431888_0.3734499838120189"},"_hasShrinkwrap":false},"0.0.0-preview-202178182932":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-202178182932","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-202178182932","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-202178182932.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-202178182932","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-gVAr3A9uHdqeP177vOfrqGVPG8O+njVYSgLoh7T2qdaiUUzOXe1ILHVfyNZBySPThYuheAGOl2h7UFvxg9QoQQ==","shasum":"70bab1d3a661c6388e8fcd1e32965a7a276f7abf","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-202178182932.tgz","fileCount":88,"unpackedSize":222796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhECKhCRA9TVsSAnZWagAAJ7QP/2kRf097ov5cYuzBGMQL\nQ7gRwSxeMhUbbUyFxzQOn27thzfUwLoGXqpWfxhxRfBCeehrO3shVPcyh1XX\nGt5U4lTr5ghh70VETD6pkS6M5YI0RVOWelyLx9AylWkl2Ix6asZgCBVEghEb\nD/jV1ltMolx+HczzDPJGm6W6ZOJ+dAOyeV6XkckefWZyqhTOiNRgHFBWSP5S\nXiI2CO0nztiT1P4b9pUnehgppT6+jlq6+cFgMtbXYR5uGpxc3QkOQLh0m5u6\nBouhO2uBCyUBKHL7F5P5uq99/Hz8VdqRSBwz7zLIqnSlIrpZePaPANYzyBdD\ng313vVBWn8Omx+VP1sRgm6BmEf4kfzOY7dIO4Tw9RwOq2JMaj0/RVeC69DzL\nFsR0E6G7YQup8sA0bRgjude8ebLkr7spjWox2MVJlycy922y74qn6wZRHjhK\nZL69VBf8jmtezqXwFFcrlnWQa8hhHEaQBIQdcX2nbvbHvHgMxqyN9Hz49Zw/\nPxPd9vAz5s3Efb7KvX/eZCEr/MIHW8mwDphJ6FLG3iPiNa1gMJM7jx7JeKLd\nvnKo1dZpGMiyyT4+w9Nb13dD7aV0r7mld3mQI/AMP3epNh5VhXcS9TTLtCvr\ng8gBod+7X+GNQhwQJWqAUgbk+r1WsSOG0NQ0n39KBVr9RNEnlw2OiFZTtp7U\noXpy\r\n=mVZX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDJ/II7zLDkomvR2Mu8WzDuaMuvcItLIhkHomBBMpfJFAiB0bxHQIa9ZE7CHwQAHFp8PCR/M+xGag8JvJ8f0B9RQjw=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-202178182932_1628447393249_0.3642121150668258"},"_hasShrinkwrap":false},"0.0.0-preview-202178184810":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-202178184810","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-202178184810","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-202178184810.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-202178184810","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-0SRiZk8BJ9q1oNrSgA5atVWBqL0lRmycPorFQSAhP4aWszCYbjw6IYLoy7uWuU+2rJ5oCBSpbILlLNZ6dI3ogA==","shasum":"3bf0fb147f32e9c38890530d8e20c823a120387f","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-202178184810.tgz","fileCount":88,"unpackedSize":222796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhECb8CRA9TVsSAnZWagAANSoP/1yl1mqrrfl/f93qkZOg\nFOQLRKTptKetdmYrJlEekFRglHki5+x6WI/dHx5JHTxcZGT4qe5WG08pGRNF\nq4z3j19F/iMs7SLN2xnn5nHryZautUkK4vzz17W7s8Ku/DDK399hFEC5KQt7\ncpgaaJV/7WBFY/88GlfGHgCgrufZly34QsHwQe5IH8CNS3YpDPkg2sDWDmes\nf+qFjmXNPPMirzzbuC7JYt1X/qvwUA9jI6mcZVvf9N0qwLOPpatFw8fOGBd7\nxpQuVBRqCCDmjjAutzNUd2iQhvkmHHIO52rDgDc3f7XWMBD6S7Kgi4cgXGW/\ns8/nIiny2hZ6Cggi7FQOQcO/ohbPjF8O+w4YuDpF9xXgDpqoMzrw36+E8XRl\nt93OW2jrqqoqT0IoPq1eTqB8ue5tfNpHsYiXON5tWdQXEThzNEHr1Y3GGETt\nZ7jXjZTIPY75UrwpUT2Vw4nJjb+XxGKCctpu563isIur6/uhQCAIKfIxyVLn\nW1twdBGsKPE4r+UXS0eHD+FBuaDswKD+LMCghJsEw/f2QCXnsfLjUAR1NlrS\nSFIhSKXhrX88GZvcSBVukIpiTzarlYCd8/ixjzoG8m9BdMBmJ5iQNesDE/Xb\nYBHOIH7G5JtsowizPuTLzOzsq84XivYrg2V1tAzXkm5zB/akJxm69MJKCFs7\nan7L\r\n=UL29\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0XHfb8rvYHEJRTIMvWKXOnxYO2JsOUC2WL1tUZZsb+gIhAOb6Zd5hSUaChnVbqwxMANQR5CtBwJu44CgDuPhn8Tvg"}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-202178184810_1628448508483_0.6576824299823025"},"_hasShrinkwrap":false},"0.0.0-preview-202178194614":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-202178194614","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-202178194614","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-202178194614.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-202178194614","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-qPxp9eiUQbzo6JgTff7wBMOVyWYR6Hlt2EbrEtkw3XX05f0C5ixdqLj+RFxtVJhQN1j5ComjEWIS8d7s7BFG6g==","shasum":"8c6be7cbcb4572fd5c2c424793742d43d3ba6aa2","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-202178194614.tgz","fileCount":88,"unpackedSize":222796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEDSZCRA9TVsSAnZWagAA7dMP/R+rrGBkG1Y7f15LFcYR\nnOjWQrYoHcLK6liGfyjfW4ghWiaEXICRwvk/uJzD02775Q05uLFDsecdV2vy\nNs5VNUDB4uYqv23GHNO3Xh/VX0MqouQgvIYmP44k0J0XEHz7jBjj2ub9/71y\nxnHYBij04xsxqkSjuw1VzHZ4F6ZR/TXREG3aNlDu5CkkY55wummi4GeaM2SO\n+vdaW9At9lTFuwwR1r8bp7czicmTpp2R0HsYRmfNswA8jPKb10gsSd7b1jL9\njBZy3+PgKaIyl7pCUwjqZydBJSNEkTbXIUBDD6sJRcWjmCXdsudcuYCQ8XAg\n9MLlyRdQ1DvmmeNIBVpXAmoxQosiiTU394asNXcCIGLcbn0rKUmywOutYgLT\n5GYm5YWMEx1FCMLA8wnHRQn7pj+UKO6PbjHkOxZI3tEaKlNejmsAofW0/YTG\ntzSOHLxNo9a/ispZ17FZYiDJsS74deW3ZskHfLiK+yYNE8P2yIiuH0BVufv/\nkc7QfWYd8GJquf9+hJBAkcMYr/E+v2HI38h6HLDpDoPF7NGjyntMetnV7Wb/\nFKdVExpFqUAGKPPGbc2mkRwNU+yOrOfnCSuyCQRD7FFLDEU0L8FvsgLSB621\nse+GaXsIn00ag+tTPHlW5szYbfKAgx51U+52vdVGlC8TU1begk3uCyUyedgh\nWJ4x\r\n=IMiO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICbIBep6uR/OdIKjeriav67c2ov9hAXeeAztoI6vPHkoAiEA8c4g2eht7qQvVJRS/f8X/XIV5GsQyrJCbU8WVP7Dcm8="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-202178194614_1628451992985_0.8239652603701797"},"_hasShrinkwrap":false},"2.9.0":{"name":"@giraphql/plugin-scope-auth","version":"2.9.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.14.0","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.9.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.9.0","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-3MUkiS1RUW7P5dyQE1TXwImaa8F96k0veCciYefLlr9mXCdPqUgxiQgWaeU45KQ1PSS3LPbjgOZShvNQ4qaUYg==","shasum":"efb22eda4bdca9f3438e7341a3a43363413af3ea","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.9.0.tgz","fileCount":88,"unpackedSize":222736,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEDcjCRA9TVsSAnZWagAA8ToP/Rl71P9+fugWVvvJiRv7\npCRBB2bvJlo18h8/TsUTw/U61D1+Y4TrXKHobkMpAiJsYgkJy7X4mfnu7k2L\nJQQ6QH2G3EoTV0rsEKAH+O265+ZwGHXzuua0PJhltObunlsxkPTGocCigPp/\nL+pbmJXV3ys0RTqxm71322TpuV2VVELjS5UW0Tx2bAHJwzNJI0p3FmNPGTOa\nTEDctpd3HQaJYKcvqv6UaEs2UX6scCz7IJ6COsMdmj1HfsgY4nNNvYD9XaQp\nPUpW1CoF594ti1j9IIAnC5foN1gnRfxA5XxHDU5iXC7yFYvIcYf9mhnl3S2l\nH1zCzaLLO28VKqFlOWTHyWT/2jpWAUWpQD+Usu/AODYCuybQ8TtNMBBd9Wvh\nq0IvFG0c2FLvswvKOZCLM9Rm4YTW8ssB+kuBn/bS4MARZMAlo77MbEjScsaB\nDjTYDtsph3a3X7YpmZuAGxWRiXCT58satlS1PCOlhy5RxnTp39WVqtE6ajpu\n+lUKuQgi07SLUrN1UdTR9dUKQ68/vbAaFqQK1qKW5DslU50vgYZksKBaHA6t\nqmGVka7aiKARucEXF56EdHSiYWG/WyxYBgV/IlDZIJf9l8XojPMv7cn4xKmn\nYQureaZWO7KrraAwPI5mOGh97zMQpiMxRXLoihx30NQQjCL8YUMRk1Gs7Exz\nnku2\r\n=dWJG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCiTfthtV/PVLa3v/JTUKwZtrEWixfzCVDEktxyCCQmAAIgWlC8gEYv87wAFE5YMhiBhQ51w+83XQt8Kj+vil8HFsg="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.9.0_1628452643534_0.5330413967316019"},"_hasShrinkwrap":false},"0.0.0-preview-202179204139":{"name":"@giraphql/plugin-scope-auth","version":"0.0.0-preview-202179204139","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^0.0.0-preview-202179204139","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-0.0.0-preview-202179204139.tgz","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the coolPermission scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the coolPermission loader will be called\nwith `readArticle` as its argument. This scope will be cached, so that if multiple fields request\nthe same scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@0.0.0-preview-202179204139","_nodeVersion":"14.17.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-8osKPL6mOfYkNnyoyX+Xoxix2rCgdgbeslaqhDtaX2NcdKI57FNYWt/GyUy7FI/wOsXFZrcfdA3nhreR8SieJQ==","shasum":"c0892e1d3bb6c2720497ea4066ad0cc1331c0029","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-0.0.0-preview-202179204139.tgz","fileCount":88,"unpackedSize":222796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEZMYCRA9TVsSAnZWagAAmXkQAJwlchP7OxDwKOS/XQ9D\n2wk79lzeBYQcdwF18uz9FPF61R5ttTLZyDnfcsgQseI9j6jiCiWM0dqyxQ+i\n+8pLzco0C/FDi1AT8CxGcIjfMV1T2ZyK6UgaJMOy+KK/euwCJuiX+Jo//N42\n4E7BWZEhUfcEw5lfzLjd4unHy6VkYXyxzqM4ObS0VtZh3PQQn99n3zicUdLV\nv62eiGnt19udNVD+TcNouXA/fO2Rd9CfxHjRfc6XzkVj3CqvzcKzvAPpNK/b\njlGfRgMcjXNgr19vi1Idj8g4wdlrJBBm1EDIzEIOe7vEBBDKF0aPA+H3OvfQ\n/U97RMqzWnrzTrta0W5LWuGt1mG9dg5QGpnSWYY/kLjwGpL6262pT3dH07QM\nFPhTGhUAlx3J3FCULir09ibSvQ4jSx60iw34NbP0EcfkxIT49NDh/lfvqE6n\nC/kabwm05t9OhXQy6MfELM5EjIVhPUppz01Sd1Q8lqKPMVQj4HsU+UQy0usG\nY0g3oVOgHoo9cb3lR5n2F0bBdJCUZ2PkiF7UD43fXs6hYb2lYHg6tD87rwrz\nuR5i0MSMZ1qzgtQYw01O9swKP5vKx4Ngj7FSCP56pFYyovKiq6qHUGDtW1U7\neqxIOogzQTz5SlGb1ogcyG59o20ExHPjrRGZZ7ChvDUIO7II4WY7OfeeWb4d\nzA9O\r\n=8AvI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGMO6gnow6CCdw6wOrPLa77TndZivCqgXXnZns+fEZQQAiB7tEuFFxM+PEM9THm7imearf0NVqSiEQTNC5gheJkLSw=="}]},"_npmUser":{"name":"hayes","email":"michael@hayes.io"},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_0.0.0-preview-202179204139_1628541720750_0.7924788339521514"},"_hasShrinkwrap":false},"2.9.1":{"name":"@giraphql/plugin-scope-auth","version":"2.9.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.14.2","apollo-server":"^2.25.2","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.9.1.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.9.1","_nodeVersion":"14.17.5","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-WugA1xifSWCPlEUxE0Ea6mB8m9YLpUrJ+YwXy5y1ur0VS34Hv+/95FFf7YjKmFHGj1ecFBEKUz0LfWnJCWQwFQ==","shasum":"b7f68dcfb2fe3af6336cc506a02d38a934c04016","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.9.1.tgz","fileCount":88,"unpackedSize":223414,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhKWbaCRA9TVsSAnZWagAANUUP/Rpelgc039UuJd/1wykK\nDy41lUePKdbZ8LACSlVAGaKpuzSBB3FavXOPwd2R+pHRibyxXm756VPJyIka\n+0tGrXvzFDzUe2Jc20492VaVINBtrhiTEBkVgaQf93bN7W33jTLsoCA0Aw8T\n96ZvtDuP+OL7hv6hYX/fXZlVjdwYmfsf5laVM/8W8WpfTd48fZf/5OUOL0IE\nrG3/haPci7EMJDdnMLwGRqqBCdZ2iP2Y3++23eEp4mHvFBTmeYZ0Hg6/F1+O\nZ/dWIcGBrrKS3zcTm0j23pv7eX6yoCoqWE/gBEphg99l27U3GdKqcZRb9/Ga\nHcIWKtgWKMtAUZaHJ4ejB+KgbWgtesULxRLyVd4yp7RnM/YEK6AeDZafnDEO\ngGqxBNHTtgSUCppfTpRhIuqWHEBZzSDnNaTQiOphOPg/ecxhCAcmJnSQsEYP\njbrWvQQBjy/Gj9pea0ul853kHD8UpPCjJEkxyu8Cctq9bfkO22ms2J6hN3KR\nHWFarIxGQ5TY9ydMR77nfrXOfkJS/3bgVlZXjuVk8lEjcBttgn91KmRs6CKZ\nxHWmzXDXEd5vTJG4kSNKPkBLWPNWhvnWWefT3e1vDJu0eH4zgPd9+leqWNFq\nMO1l1wn6Hpix9VbdK9nzYoiLo9NWfMO0IqIyBve1NsqgWVdOlud8puJC/Xqq\nuynj\r\n=a3GE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAcJqiWjqBOOnJ4I0K/oJk/BotdPsHhlV2hGwbudULw8AiBtFH/KwceVIEXvIww5YhzVcSBrFtjgPim4hT6iEw7aFg=="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.9.1_1630103258793_0.44385605823585883"},"_hasShrinkwrap":false},"2.10.0":{"name":"@giraphql/plugin-scope-auth","version":"2.10.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.15.0","@giraphql/test-utils":"^0.1.0","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.10.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.10.0","_nodeVersion":"14.17.5","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-r9JXCJWDfGrTrB5c9jaEsNeMrdJUbBEdwK8iwdZ0EGTvpdkzzUlYr7xADeHlIJPTX+C3PVjaLEhAhL6mDhzu6w==","shasum":"090aac1565d81d104eb38edbf91667e18295c1b0","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.10.0.tgz","fileCount":88,"unpackedSize":219187,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhKzlJCRA9TVsSAnZWagAAZsYP/iN92YH6Y8MUUDYqCCR6\nR+USzgpnQ723bEEwLDOBR6zhfboya9GHQsA8GoJ7L46CoW+K6ST0ka/IPfxo\nGc+GjBM4mMr3yxCy+iI5y3YDFaRhzUWaGP6rAs4709I8+6jz8BaFYH62UOF+\nLIaagAmlsmE95A3uXF9cJzxZDX6TrBIgNqDRG7IGPuyJEYOGm0r5a690QyDt\nvnXbkv+DbTwjk4/6MAmsxKWA7FoIgJ0hdGZTR6huSFsty+OH8MxCIUJYZrFe\n8K7+P4IshDWzxI0plTHUd+THU3IjQ00vZ7SWr85yVpsBzqI0salduqzBEUS3\n0csx+ERcvVbuMaQkUx5MidmiSRFfiOZtU9rSwfKVT6ppa+VUelJyEgKxhfGv\nYYrkmTgBl6WzlEnDxPo40adKi3jR7xCGwswUBv5iELz98jgEkXcs03sWbYzs\n/RA2gux2fBOFn/aOtgB4z44qLs/U/4IMCdubdwS4v4iIIFxS4oJSfd03BGIq\ndDLvkd56eIkmOvV8s0E25BH+w/qxcWCcPdV/kTvIAjlRu/pWm5sKx7aeucW4\nqDT923fFrM1bT5T3KANz02SLiZMIJF3x35rh3n8tEChXJXk6JI6TvYitbxSi\nHex6vQKfWiV7c+Tjfyih5P48VlXPYPKdjJD44JfG5VcCjEw+ysfbmfZRuRHA\nDjMV\r\n=6lXa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEnYqwbe8hOVljt618dfYcrI9jOAG+4qUEzjCFkSjLPpAiAlIu8saJ3djh2gU2wFtvSL6SQWG/v/27UOzF/3Isfagw=="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.10.0_1630222665703_0.7065378471568804"},"_hasShrinkwrap":false},"2.10.1":{"name":"@giraphql/plugin-scope-auth","version":"2.10.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.15.1","@giraphql/test-utils":"^0.1.1","graphql":">=15.5.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.10.1.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.10.1","_nodeVersion":"14.17.5","_npmVersion":"6.14.14","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-JrNPU+exsEKTDiiiWsH2BH/xab2IRtXHmcxav4zWBDztSFJDhs/U0jJIeRGfctAx9jnzhiKWIJnA8KV+xNm/ng==","shasum":"0b44dd6b0c27d379d5e1b6d495ab778211836612","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.10.1.tgz","fileCount":88,"unpackedSize":219286,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhLRigCRA9TVsSAnZWagAAJfwP/jqpknGmQA/7ThUbz9xG\nQ/p2QLLaChwCoGF5k4QyH3nsPh/GcLjIfvapvxMoQ2ddpPx157yVDoVkPTZz\n4OKhilqOnWN0PnvScq6QXFjfBpoNTLD9hZwolsSKGeIR7a2aAucAKF8F6YSE\nZ32XETmSpxAa/dKXeTC4C3u0ABxeLJrt8Mhekv+vtP9vrkLZl4c01HBssy4q\n71+Couy1BCJGlkex9avbQXaBlqHUjzKGUohXkvrJsYY5Jc8PPiZr3dHbLttU\nhoz77rK/zC8lfuxYG+ExQPoEKFA8mWl9mirbz85hupHyb+tFPxJ99nt12jGZ\nz3/t+Zl2wR/hiI8XbTZ/ux+z0GpMvm43swy5tmXDJj/H0YC7QalkWAWca5sX\n8L/PuGzTQYsl6JZ+kGeLiLMTQb1itJWZwHTQaP72xTpSCbFyIPvOpkav/24K\n1LBxjdXyts5TjQNRmCWsEXz0bKuwd4+WdWSoZWu8chVlGHXZBc6n3KHojh/i\n4QIO/a83JIdXrYs0p4g0eYpKm805awQkzNONf+9Iucl22/94aoRdzgPEdHSZ\nZLqXcLVYBb7iOVPWQBw/5D+zV8dM2FE/gwnvSpI526mjhmfbsg8ANtZ8jqWs\nwt6vuYW44ijYPZdrXwi7H/75MQ/4vosrixd4qK3ZhoclzH4o1sb8vN0PRXzb\nXPXB\r\n=saCt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICz5EjR24ENz58DAznvP2Ndw9ybih1T+7OJdC5NtPK6cAiEAlnTcGt3Wcgfeq98ABoRGeYtNlELOTwRTwJ11OYXfhdg="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.10.1_1630345376611_0.9426639144976803"},"_hasShrinkwrap":false},"2.10.2":{"name":"@giraphql/plugin-scope-auth","version":"2.10.2","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.15.2","@giraphql/test-utils":"^0.1.2","graphql":"15.6.0","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.10.2.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.10.2","_nodeVersion":"14.17.6","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-h1d9BLF5/bpZdPn4wSfRjlEORHbBLTOtJrt37MN7rLCXVVPTOk8wvgmvI3BAM0wHvNuE7dIQgTfCsjQVP/4HiQ==","shasum":"cc1f9be769ef5ce58eb65b2c2cf470d640da8384","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.10.2.tgz","fileCount":88,"unpackedSize":218775,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD5eFQJ6suzMtPLDHS4UwT7p48BhGoaMAGiBN7SU4Gt+wIgc83vt7p/xOKvUcL90oyNMyV5DE8bMynU0QqFJM2fWYw="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.10.2_1632278622213_0.9794666597794135"},"_hasShrinkwrap":false},"2.11.0":{"name":"@giraphql/plugin-scope-auth","version":"2.11.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.16.0","@giraphql/test-utils":"^0.2.0","graphql":"15.6.0","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.11.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.11.0","_nodeVersion":"14.17.6","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-j/U1xSvfFXENTJh1/Q1Blrsk+WP4YtPW7Yrx3GVmC1daoViy1128GmC207WKYUKJu/GHsHWcfAhgu7BuVNbr2g==","shasum":"297e15ef1cc360cdcb64a704558b33f1277e95ac","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.11.0.tgz","fileCount":88,"unpackedSize":220873,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICDo1X17Ef7qR5/l7LlbmNu+JnGn9KvvZwEOs4h4Q320AiEApuEouyYgP5OyCjYzjPRuFsvsZfr6xAj7fzlp/x/Qtm8="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.11.0_1632971282479_0.7752776058510547"},"_hasShrinkwrap":false},"2.12.0":{"name":"@giraphql/plugin-scope-auth","version":"2.12.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.17.0","@giraphql/test-utils":"^0.3.0","graphql":"16.0.1","graphql-tag":"^2.12.5"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.12.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.12.0","_nodeVersion":"14.18.1","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-LmwhLYaxvmz4NQnbX8Mnc2qGhhHY3nAy2KDVx+9/7R2jEp7l1T+uNjTgyALWaAiRy7I0vqrqGZuuxEwcwzKWFw==","shasum":"cbb861e4207a4db3aa3d2a1196ff15659acddcdf","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.12.0.tgz","fileCount":88,"unpackedSize":221259,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCil5UegQJYnTZaVvJrj9RxXdyFV47q5iixz4j3bNTsKQIgb/y1p0gA2ymod6CzeAbT3v3xXVp8B2gW7O2l98o/Gj4="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.12.0_1635985516943_0.2920777019891496"},"_hasShrinkwrap":false},"2.13.0":{"name":"@giraphql/plugin-scope-auth","version":"2.13.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.18.0","@giraphql/test-utils":"^0.4.0","graphql":"16.0.1","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.13.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.13.0","_nodeVersion":"14.18.1","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-/k+qg7nJXOATYirZbY3DoZSSkzMsud55Vj8wOz8Ghk4L0f209WShUOKbuI5kSEe6goSNEL4FRh5+TgSVHwu8Ug==","shasum":"fc3dd82d5b933c09b44132395b23f4fe44170204","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.13.0.tgz","fileCount":88,"unpackedSize":221322,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhlEjGCRA9TVsSAnZWagAAwBUP+wYu10QtNtMY6U3RdgYQ\nBqy9fezQ/BROnhGrxbBxhUdQnJ/jAQ2qTF6opJ0CgqaEcvn9YPplxUYDIwp7\nKb0EIsZv8rfuI3Nt6hEQ6EZJIm0uSrGsMOQqPwN7g0ZQa8uzy9oI40SxXUDT\npLBrZs7/O0vG2PbRxsQQdaZfQ+6VJRNBdOG2QKSApLFlTInF2kMCOA00eZdU\nZNvbySqK7zvO+B9B/9ltBLHFcb1e70CcEJWHaPDDlE6d3Z3BAXM7twEDqiA0\nHxZ7V++BUGKu+nyl2SdfVzXHZgzcGSbvI4tvOaeAFsl/noC9BvT4DSRVht2f\npZ2GRzqCmkKlpGt+2iO/XIaED205e4IyE2Qc+mVBuRRyxlMDSlrQzDK63roX\n9niOWonACnCeUWwIcQgzkdIsbiEz0+9seq+y2XwZ5ZOxK303QLx+N2iH3NGc\nSBjh9pPRIGGBY0WWTPZrmN6dZeJkkY7t6qmRr7tvQ2G6tib/JIndKKcnze8F\nMafT/lyuINHI76HahohcDqU8Zk0P8tqRfQCCaptLfwD8A8r/B9bPPSCrJMm+\ny/bFvlADOpg96l3unbmiGO36pxNgpZQUxWNWqag0JDGqHMg2YFhQ3Y3KJtAt\nPCXoyAphJ4b2lVOQ7UPdplH/LekidTL1TbbudE3F59NJIJlzUBbm2CaI8IVi\nI7uH\r\n=IQJF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAYIrDnduruEudGlbnQKlJLm/9YYxAmJjhoWwttED2d5AiAWohjRAL6V6qD01edejoDLlbnviRTobCr2ZRkKviDogw=="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.13.0_1637107910299_0.29431257955735024"},"_hasShrinkwrap":false},"2.13.1":{"name":"@giraphql/plugin-scope-auth","version":"2.13.1","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","types":"./lib/index.d.ts","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.18.1","@giraphql/test-utils":"^0.4.1","graphql":"16.0.1","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.13.1.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.13.1","_nodeVersion":"14.18.1","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-nmJ2qeN9ceqHpMG+swPHK9rQdTWoVnrswrP06V6Ilc+hxwyxW12VBY3IcuLOqVb2uJemBEfpUBPc+/CZM3yG6g==","shasum":"f9a019b67900e0a5da0db80ec5f76f5d405d6228","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.13.1.tgz","fileCount":88,"unpackedSize":221427,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhlHFpCRA9TVsSAnZWagAAkZsQAIvX8mruwIMUzEujTVof\ngIfnkBufD4e+hiMNdqdYUioxvmgiGrMKkOqg8gahcnMz1MaS/fQv0m2GIsMD\nMZh58BGeGUyYta0LslO/FKj/D04nAcNOPp+T1c6uZBOnUMXyWr1F6MHFg8QX\n48LLW6uB2o+PUBKRdz4ozHMQwvoOYms3LTv0d78nYx+hl4EUi4sFmRGwBc9D\nkqc6v/m2ZMPg0aL3a8y/cENGQr4kaLwa3nd6h9Bryn27ZlVOeIX/FW8jSdJs\n1GDmgG8UtHX79XeuV9YdUMcLYv3R9kqvazEFnySsZ30GFjQNjdVuEOKCpwhn\nDvo8gPkzSXLR0eqzBcNHvgoQHsKmDnm8L48kry3JzpP3D3myZOiQP9qwiVmy\n4lwSMZ71xtELWmVx7scYCoXYQC5EyBOLYxtepLnODNanwTDum0KO7ZFj5o2D\ncvbI4AGMeeifXnxrIo3D0s47jP0MZXumJZt6hX1ZnpjNBaEpHDYTCfQLKSAr\nTopIUKzPrxem72cZC3enYa2uy88V5tLd/2CjXWAvau9jxSAbhrtguMQQEHnA\nif8CDIlq+5QkQGZLVUhtFw0KwR4KWU9iNC9A8Hj7tNyrAu7Ng3zrypfBh9C9\npwKWKvrVc1DFEgDgx94R8QNs+75KkaWmR1h+FHkm1gfQB3NmwskzMnasx9nW\nLni+\r\n=7r5v\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDmlah5JvbOzqzKFmIsBb5f1l8tb5TT3FSfWusYbEmlgwIhAO+71WHF1LbScISMk0/d5+OX+IbVwxY+yidVjyDjAjnI"}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.13.1_1637118313570_0.457697022807384"},"_hasShrinkwrap":false},"2.13.2":{"name":"@giraphql/plugin-scope-auth","version":"2.13.2","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","types":"./lib/index.d.ts","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.19.1","@giraphql/test-utils":"^0.5.1","graphql":"16.0.1","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.13.2.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.13.2","_nodeVersion":"14.18.1","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-WE6T8gv46NQh76Hu+UVqrlBIJMBEUcz/v+O8F2t/seAO5/a3SrN4GETtfZ+IqozHKtWMBmAl1UI0rP5DelpsTg==","shasum":"8c0cf5eaeb358ec9fb7911f77494f4dbdaf8074d","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.13.2.tgz","fileCount":88,"unpackedSize":221722,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhpb4vCRA9TVsSAnZWagAAW28QAKMuiBCJdo17bidecb99\nEdCPSUxXBjMqQje3SjD8m5XsB02M2Efh9SgI+MCAzSHaSfbl36PZtl3oCg93\noWpSa9Uu4j5jZNevZZJECTgBGVxI1wIini+ce0JVnvd2QfeECmgJDCAD9kfn\nxxPUhVqSecQJT4Me/zzWZJkjGzW3x8VcqYd6jduBe+2ftYWJAIWxpBkSO1Hj\nd52SNOt/Xu1moZpAtDLazxvRSNHF/4V0ZWuDyT7XnFSC29S5ZxCcfxmo2Zsx\nJl6RD9TrBzHvM9KNu7PtSmeJStF7pkVKerqj1sWvt6okvMpsT6q+LYOjpRUK\n2Qk2cb8QfBg1SQ7TjAzyVsH2fzi2Mz6aVvM7QPa0GVRw+q/YnKsdYtbsA6Pi\nbbd91g+EZM71SA2SaeDW7KtMQDRMlh880bISDTOwV2i6GLN1/l8/GVwfbqds\nMcr2tNDehr0lzCcjC/WCdzM6z6WVZFE//7RX8ar8es0BkPzsFHryppUNy3Cp\ngthiLZKhrFmn+ayGSCkm56eDjCb3TsJLSWagdGvGoY0ymBuNyhuLzJPgCupz\nlTU4/a3VCEWEgLpvrrp1UXCj9SLYMlFjJrc9aeo4fT/3O8BkAcBhRFiXSLs8\nN+b2vst+7mT//3eqKF/NFABCAzHHZB5hZKc0rPacgcxnylf8RbsVqYJqiajF\nKfR5\r\n=FMfG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDMi5h3To/obPH/A3x2RXOfAYA5D3y9z0Tp1nzxblRrFQIhAJQtfPvvAV+R6OGmFggTJgYv4oXLhARnxjLlepWznd8h"}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.13.2_1638252079327_0.2171596919847889"},"_hasShrinkwrap":false},"2.13.3":{"name":"@giraphql/plugin-scope-auth","version":"2.13.3","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","types":"./lib/index.d.ts","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.19.1","@giraphql/test-utils":"^0.5.1","graphql":"16.0.1","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.13.3.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.13.3","_nodeVersion":"14.18.2","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-k+bh9BVXy3BlCBNoucAZNUkUbUj4/LaqbvEccSzkdELrM+rskpGs9Qc65jO7QzvoOQR+vp1Oa/8ll/f5flpXMg==","shasum":"c58e9b872d66a83a3084b9e8043557fd07e7a7ac","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.13.3.tgz","fileCount":88,"unpackedSize":221821,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJht+ySCRA9TVsSAnZWagAAEzgP/2ddWatmdHpZOaQXGLBq\nLOgNPTaJNOTGvnu4lclpcMUq+ZJjY+sosjapTzYTMEOlSEQl4QRU70NvRJRO\n/uzP1GyzbL17k72Mv+auBuqlEc+UanolRe6WXhxUo3SCPs5gxWFC2zsBgvWX\nqRfCrAZaObzmDKL5xQiG/bHsQiDNtIvb6KYgoQM++SzX7x2hxtekZ5+8luyv\nHo9la4+MrstQhstm9ycxBDAuIFzNHIpDfLHslrfTPUF0rNASztVcEYo60mon\ngifesmQTaSma/qS3V6JZcxmiG1Z5qyKLMudGIhJ0NbHFUomWtTDDTxu666Jv\nYciAiAxQ01ejo4AB8tpBBFb2zzmGARYuq/9ciWpf8qLlg0IaXeEjDmnZgqTB\nxZMx8Qof1NvgE8MQlHjri6tJu6b95JQ69aK58nAr3NpdTJYuVbI6zhP+dXwY\nFAMwwsqNJWOi1ej63h/FwtyqtnmuJ+DEyMBqbZ1y2z2MMjCaX3lQ7cm83mW3\noxr05J6fyiUWweih8cQT6wKXp3z5c1zfryLMzI8IiOTqOuaFwDQFtIR2hWtp\nO7ZurvRPKgnZU8RyMQcCUpXMao2awuNp8K+vvSnbn2FBQcOrLd7XUuW1dVJO\nHi3hkIh9mNo1vKMABSUXJ9HWPuN/zAZj/kdXkFVzAisXIM6ALAi+/xqyadkX\nLmck\r\n=xaGb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAxQQYPt6ngnwPw+j3V8A4whAEEphdmbTtYizMxrxZoFAiEAuQ1lEc9FuxTuTpum3Q+rwKP3feaiKNi2NgVojTvbkaE="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.13.3_1639443602539_0.5548125494572942"},"_hasShrinkwrap":false},"2.14.0":{"name":"@giraphql/plugin-scope-auth","version":"2.14.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","types":"./lib/index.d.ts","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.22.0","@giraphql/test-utils":"^0.6.0","graphql":"16.1.0","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"type":"tsc --noEmit && tsc --project tests/tsconfig.json","build":"pnpm build:cjs && pnpm build:esm","build:cjs":"tsc --module commonjs --outDir lib","build:esm":"tsc --module es2020 --outDir esm && pnpm esm:extensions","esm:extensions":"ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" ../../.config/esm-transformer.ts","test":"pnpm jest"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.14.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.14.0","_nodeVersion":"14.18.2","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-eev++NzpldQ0A0lGv3dfkEqqQ3/ALoTcrXMizKPo0HfH+mG9t7vQ3ozkSOPr+inlhpxEdaeQghHiy+UfRYNLFA==","shasum":"cfd4076eb149baafe8b8a30b51f00d00bac7f280","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.14.0.tgz","fileCount":91,"unpackedSize":225622,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuX7SCRA9TVsSAnZWagAA7vsP/RMEDthECzjzpVB3tryx\nu8dUxaRjw4HznF9I2JSgfXEQvM66g6jI15fJUANSOZZzpsvFS6ol7mCFCPGb\nav5F+dM8QentEfRwebZchdnn+l4Zw7TTqNYBIxnVXx6pdvL2cmvW5qVGobCp\nu8Mk+pqpwKyCNGbGj6tnZuUuRzn/ouJ+gmSZsJz8eVY0feifSVlgURmXqk67\n3/Gxa+Fs1Q2MK2gFtY7l+Te/LFqRGnXzH1lY84kG583L8H7G5uXtJTNHFh99\nyo8PBcqJjKb+1CUXfq1nfp7u3DwXdUFoQ32WUCJaPbAXvMvXWNrh929RgwOv\noW9WFojPWWMzfAp5ymDQS5ZsET+o+GpBLi4z/9cNGJNRY3pcjMhBcw9yAQ7q\nh1U1hKyiDQsyY0RWolfJ/kQx1RmoT0j2yuVV/nhMNT880nZtvpXzrBvfHb4E\nNbloCAMvVgQCyDQFOJ4yc2IHdy2Wpdq10o7jONmEAt3TTbf49X1YGGlgiRD+\nwtS5nxxF/MiDIoV3ZmvC+OyeyLnnP1RlqKvHXezLOQwb6dZhwxG/ie08UNMU\nnJTwMhEJZ+ojeRl1qRYLlTcmibqKtj/3ztyhnoqtNdEhCVvqgHUPP37vwaSN\n9+jdFPUNGY1bj/9szXlhwldN2TehdQ0OhuUFOMqH9TG5eHgqVydvzveRnXe8\nvMAs\r\n=jlBJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBk7QvBMEFcjz9i7WTy/0d7zs4uZSw869afJ9SBgldPSAiEA09fNJjaOh7EXNLCAnJLtnqWnDF065Wr84l2EJYaW0Zw="}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.14.0_1639546578646_0.8820540765354377"},"_hasShrinkwrap":false},"2.15.0":{"name":"@giraphql/plugin-scope-auth","version":"2.15.0","description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","main":"./lib/index.js","types":"./lib/index.d.ts","module":"./esm/index.js","exports":{"import":"./esm/index.js","require":"./lib/index.js"},"repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"author":{"name":"Michael Hayes"},"license":"ISC","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"publishConfig":{"access":"public"},"peerDependencies":{"graphql":">=15.1.0"},"devDependencies":{"@giraphql/core":"^2.22.0","@giraphql/test-utils":"^0.6.0","graphql":"16.1.0","graphql-tag":"^2.12.6"},"gitHead":"9dfe52f1975f41a111e01bf96a20033a914e2acc","scripts":{"type":"tsc --noEmit && tsc --project tests/tsconfig.json","build":"pnpm build:cjs && pnpm build:esm","build:cjs":"tsc --module commonjs --outDir lib","build:esm":"tsc --module es2020 --outDir esm && pnpm esm:extensions","esm:extensions":"ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" ../../.config/esm-transformer.ts","test":"pnpm jest --runInBand"},"_resolved":"","_integrity":"","_from":"file:giraphql-plugin-scope-auth-2.15.0.tgz","bugs":{"url":"https://github.com/hayes/giraphql/issues"},"homepage":"https://github.com/hayes/giraphql#readme","_id":"@giraphql/plugin-scope-auth@2.15.0","_nodeVersion":"14.18.2","_npmVersion":"6.14.15","_npmUser":{"name":"hayes","email":"michael@hayes.io"},"dist":{"integrity":"sha512-7q7S9n4Avmmsd53KF+M/VUmABXLTVCn0Sf0tx9PfILdML1FsqiSvxYc6kPQzAht3t8SUgtuV1grj54J6DXqySw==","shasum":"4eda66402c789b64726c13fefc43c969c486abc0","tarball":"https://registry.npmjs.org/@giraphql/plugin-scope-auth/-/plugin-scope-auth-2.15.0.tgz","fileCount":91,"unpackedSize":250566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2L+bCRA9TVsSAnZWagAA31EQAI9PX40P0cKMfyJWHfYI\nOi00hwh8oqywsI6RNx5qhN2rtU54UQa3nnv+iq98WlVQD+Z0ylmvZUh6BOGK\nNMP2o3MZEPmwuKibE8qsiMhS4+loiFv0eq5Eg5j4DeKZ1XptQpxfWn7Z/QT9\nbCMJv7dIA+zPwypS/RY80eBte3ZF0Ncd4Go3Cf0jDt8YS6tsNlYo0/uS2zNU\n5lG1fqFG48AlNxbUX7VkBXGEbE01gqDZTTTTaOekWGuB7Haj8hVndE7OPcLE\nNLxvbbvO3Nhxzu6PSMsPbyt0muaQZ/laxRj7yzuEopxxa0s5nvGzfWslaq3J\nSDoy29Efg+/l2dP7wEamSfYITMSpaA2T1FueBjiuU9mzPxqGR60NJd9J94/S\nT0UKnNeJQU0OfMpl99raVgZEnmSqLj2/1u4SIg2JxDHMmIlINL2FfILItMXY\nqRJ91GHAO3cwbvg6RvrNsJ28BEZ0wfwNgFYIOzTin7paDNlk0Yfa8Nc9eF2U\nASvyX98MmvunpVhbTMYDy25d5bW972GPtn+fCO9diX7c2kacYOSXg8d8GDtb\n6jb1GIJIIOXCq2/i8TFdHrkGI6Rsjv3cUYkM33KlSm+JwKECB+KDOD2+N6jF\n49knDPwCXP6X9H8i5bJs9NKHMsPd+MziHt24tsuiB4FpB14zj3Hu2dbB5Y8F\nBrCN\r\n=eBnw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCL6CZ1HL0CEJJ1gTOSC7sV1zMJjK1GNweEGFovxAG/0wIhAL7buui4YoHZGN0dTNgVBvzerwzW2zO8/ApnwC0nH1Hk"}]},"directories":{},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/plugin-scope-auth_2.15.0_1641594779199_0.7718101072616919"},"_hasShrinkwrap":false}},"time":{"created":"2021-02-10T06:10:06.107Z","2.0.0-alpha.0":"2021-02-10T06:10:06.469Z","modified":"2022-04-05T14:20:12.376Z","2.0.0":"2021-02-16T03:35:07.983Z","2.0.1":"2021-02-19T21:07:29.162Z","2.0.2-alpha.0":"2021-04-12T06:16:49.142Z","2.0.2":"2021-04-16T01:40:18.112Z","2.0.3":"2021-05-02T03:22:35.109Z","2.0.4":"2021-05-02T04:14:58.781Z","2.1.0-alpha.0":"2021-05-05T23:04:38.292Z","2.2.0":"2021-05-10T18:01:42.407Z","2.2.1":"2021-05-10T21:40:03.151Z","2.2.2":"2021-05-10T21:47:11.440Z","2.2.3":"2021-05-12T23:06:31.118Z","2.2.4":"2021-05-13T01:20:03.325Z","2.2.5":"2021-05-18T22:30:49.818Z","2.2.6-alpha.0":"2021-06-09T20:11:03.485Z","2.2.6":"2021-06-10T00:55:54.665Z","2.3.0":"2021-06-11T07:22:34.334Z","2.4.0-alpha.0":"2021-06-28T01:13:01.663Z","2.4.0-alpha.1":"2021-06-28T18:14:11.554Z","2.4.0":"2021-06-28T18:28:36.756Z","2.4.1":"2021-07-02T20:08:55.651Z","2.5.0-alpha.0":"2021-07-04T03:32:28.301Z","2.5.0":"2021-07-04T04:18:22.944Z","2.5.1":"2021-07-10T03:43:48.823Z","2.6.0-alpha.0":"2021-07-17T03:50:49.891Z","2.6.0":"2021-07-23T18:41:56.222Z","2.7.0":"2021-07-30T23:28:55.606Z","2.7.1-alpha.0":"2021-08-02T05:07:04.035Z","2.7.1":"2021-08-03T04:04:05.960Z","2.8.0":"2021-08-05T07:15:28.511Z","2.8.1":"2021-08-05T07:22:26.356Z","0.0.0-preview-202177065":"2021-08-07T00:07:06.684Z","0.0.0-preview-20217701452":"2021-08-07T00:15:10.822Z","2.8.2":"2021-08-07T00:15:35.519Z","0.0.0-preview-20217752147":"2021-08-07T05:22:05.138Z","0.0.0-preview-20217753333":"2021-08-07T05:33:52.091Z","0.0.0-preview-202178182932":"2021-08-08T18:29:53.399Z","0.0.0-preview-202178184810":"2021-08-08T18:48:28.799Z","0.0.0-preview-202178194614":"2021-08-08T19:46:33.130Z","2.9.0":"2021-08-08T19:57:23.739Z","0.0.0-preview-202179204139":"2021-08-09T20:42:00.901Z","2.9.1":"2021-08-27T22:27:38.929Z","2.10.0":"2021-08-29T07:37:45.849Z","2.10.1":"2021-08-30T17:42:56.770Z","2.10.2":"2021-09-22T02:43:42.417Z","2.11.0":"2021-09-30T03:08:02.646Z","2.12.0":"2021-11-04T00:25:17.082Z","2.13.0":"2021-11-17T00:11:50.487Z","2.13.1":"2021-11-17T03:05:13.728Z","2.13.2":"2021-11-30T06:01:19.499Z","2.13.3":"2021-12-14T01:00:02.977Z","2.14.0":"2021-12-15T05:36:18.810Z","2.15.0":"2022-01-07T22:32:59.398Z"},"maintainers":[{"name":"hayes","email":"michael@hayes.io"}],"description":"A GiraphQL plugin for adding scope based authorization checks to your GraphQL Schema","keywords":["giraphql","graphql","schema","typescript","auth","authorization","permission","permissions","plugin","scope"],"author":{"name":"Michael Hayes"},"license":"ISC","readme":"# Scope Auth Plugin for GiraphQL\n\nThe scope auth plugin aims to be a general purpose authorization plugin that can handle a wide\nvariety of authorization use cases, while incurring a minimal performance overhead.\n\n## Usage\n\n### Install\n\n```bash\nyarn add @giraphql/plugin-scope-auth\n```\n\n#### IMPORTANT\n\nWhen using `scope-auth` with other plugins, make sure that the `scope-auth` plugin is listed first\nto ensure that other plugins that wrap resolvers do not execute first.\n\n### Setup\n\n```typescript\nimport SchemaBuilder from '@giraphql/core';\nimport ScopeAuthPlugin from '@giraphql/plugin-scope-auth';\n\ntype MyPerms = 'readStuff' | 'updateStuff' | 'readArticle';\n\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  // scope initializer, create the scopes and scope loaders for each request\n  authScopes: async (context) => ({\n    public: !!context.User,\n    // eagerly evaluated scope\n    employee: await context.User.isEmployee(),\n    // evaluated when used\n    deferredScope: () => context.User.isEmployee(),\n    // scope loader with argument\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\nIn the above setup, We import the `scope-auth` plugin, and include it in the builders plugin list.\nWe also define 2 important things:\n\n1. The `AuthScopes` type in the builder `SchemaTypes`. This is a map of types that define the types\n\n   used by each of your scopes. We'll see how this is used in more detail below.\n\n2. The `scope initializer` function, which is the implementation of each of the scopes defined in\n\n   the type above. This function returns a map of either booleans \\(indicating if the request has\n   the\n\n   scope\\) or functions that load the scope \\(with an optional parameter\\).\n\nThe names of the scopes \\(`public`, `employee`, `deferredScope`, and `customPerm`\\) are all\narbitrary, and are not part of the plugin. You can use whatever scope names you prefer, and can add\nas many you need.\n\n### Using a scope on a field\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    message: t.string({\n      authScopes: {\n        public: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\n## Terminology\n\nA lot of terms around authorization are overloaded, and can mean different things to different\npeople. Here is a short list of a few terms used in this document, and how they should be\ninterpreted:\n\n- `scope`: A scope is unit of authorization that can be used to authorize a request to resolve a\n\n  field.\n\n- `scope map`: A map of scope names and scope parameters. This defines the set of scopes that will\n\n  be checked for a field or type to authorize the request the resolve a resource.\n\n- `scope loader`: A function for dynamically loading scope given a scope parameter. Scope loaders\n\n  are ideal for integrating with a permission service, or creating scopes that can be customized\n\n  based in the field or values that they are authorizing.\n\n- `scope parameter`: A parameter that will be passed to a scope loader. These are the values in the\n\n  authScopes objects.\n\n- `scope initializer`: The function that creates the scopes or scope loaders for the current\n\n  request.\n\nWhile this plugin uses `scopes` as the term for it's authorization mechanism, this plugin can easily\nbe used for role or permission based schemes, and is not intended to dictate a specific philosophy\naround how to authorize requests/access to resources.\n\n## Use cases\n\nExamples below assume the following builder setup:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  // Types used for scope parameters\n  AuthScopes: {\n    public: boolean;\n    employee: boolean;\n    deferredScope: boolean;\n    customPerm: MyPerms;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    public: !!context.User,\n    employee: await context.User.isEmployee(),\n    deferredScope: () => context.User.isEmployee(),\n    customPerm: (perm) => context.permissionService.hasPermission(context.User, perm),\n  }),\n});\n```\n\n### Top level auth on queries and mutations\n\nTo add an auth check to root level queries or mutations, add authScopes to the field options:\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    internalMessage: t.string({\n      authScopes: {\n        employee: true,\n      },\n      resolve: () => 'hi',\n    }),\n  }),\n});\n```\n\nThis will require the requests to have the `employee` scope. Adding multiple scopes to the\n`authScopes` object will check all the scopes, and if the user has any of the scopes, the request\nwill be considered authorized for the current field. Subscription and Mutation root fields work the\nsame way.\n\n### Auth on nested fields\n\nFields on nested objects can be authorized the same way scopes are authorized on the root types.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\n### Default auth for all fields on types\n\nTo apply the same scope requirements to all fields on a type, you can define an `authScope` map in\nthe type options rather than on the individual fields.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    content: t.exposeString('content', {}),\n  }),\n});\n```\n\n### Overwriting default auth on field\n\nIn some cases you may want to use default auth scopes for a type, but need to change the behavior\nfor one specific field.\n\nTo add additional requirements for a specific field you can simply add additional scopes on the\nfield itself.\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        employee: true,\n      },\n    }),\n  }),\n});\n```\n\nTo remove the type level scopes for a field, you can use the `skipTypeScopes` option:\n\n```typescript\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      skipTypeScopes: true,\n    }),\n    content: t.exposeString('title', {}),\n  }),\n});\n```\n\nThis will allow non-logged in users to resolve the title, but not the content of an Article.\n`ignoreScopesFromType` can be used in conjunction with `authScopes` on a field to completely\noverwrite the default scopes.\n\n### Generalized auth functions with field specific arguments\n\nThe scopes we have covered so far have all been related to information that applies to a full\nrequest. In more complex applications you may not make sense to enumerate all the scopes a request\nis authorized for ahead of time. To handle these cases you can define a scope loader which takes a\nparameter and dynamically determines if a request is authorized for a scope using that parameter.\n\nOne common example of this would be a permission service that can check if a user or request has a\ncertain permission, and you want to specify the specific permission each field requires.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n    }),\n  }),\n});\n```\n\nIn the example above, the authScope map uses the customPerm scope loader with a parameter of\n`readArticle`. The first time a field requests this scope, the customPerm loader will be called with\n`readArticle` as its argument. This scope will be cached, so that if multiple fields request the\nsame scope, the scope loader will still only be called once.\n\nThe types for the parameters you provide for each scope are based on the types provided to the\nbuilder in the `AuthScopes` type.\n\n### Returning a custom value when unauthorized\n\nIn some cases you may want to return null, and empty array, throw a custom error, or return a custom\nresult when a user is not authorized. To do this you can add a `unauthorizedResolver` option to your\nfield.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    articles: t.field({\n      type: [Article],\n      authScopes: {\n        customPerm: 'readArticle',\n      },\n      resolve: () => Article.getSome(),\n      unauthorizedResolver: () => [],\n    }),\n  }),\n});\n```\n\nIn the example above, if a user is not authorized they will simply receive an empty array in the\nresponse. The `unauthorizedResolver` option takes the same arguments as a resolver, but also\nreceives a 5th argument that is an instance of `ForbiddenError`.\n\n### Setting scopes that apply for a full request\n\nWe have already seen several examples of this. For scopes that apply to a full request like `public`\nor `employee`, rather than using a scope loader, the scope initializer can simply use a boolean to\nindicate if the request has the given scope. If you know ahead of time that a scope loader will\nalways return false for a specific request, you can do something like the following to avoid the\nadditional overhead of running the loader:\n\n```typescript\nconst builder = new SchemaBuilder<{\n  AuthScopes: {\n    humanPermission: string;\n  };\n}>({\n  plugins: [ScopeAuthPlugin],\n  authScopes: async (context) => ({\n    humanPermission: context.user.isHuman() ? (perm) => context.user.hasPermission(perm) : false,\n  }),\n});\n```\n\nThis will ensure that if a request access a field that requests a `humanPermission` scope, and the\nrequest is made by another service or bot, we don't have to run the `hasPermission` check at all for\nthose requests, since we know it would return false anyways.\n\n### Logical operations on auth scopes \\(any/all\\)\n\nBy default the the scopes in a scope map are evaluated in parallel, and if the request has any of\nthe requested scopes, the field will be resolved. In some cases, you may want to require multiple\nscopes:\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $all: {\n          $any: {\n            employee: true,\n            deferredScope: true,\n          },\n          public: true,\n        },\n      },\n    }),\n  }),\n});\n```\n\nYou can use the built in `$any` and `$all` scope loaders to combine requirements for scopes. The\nabove example requires a request to have either the `employee` or `deferredScope` scopes, and the\n`public` scope. `$any` and `$all` each take a scope map as their parameters, and can be nested\ninside each other.\n\n### Auth that depends on parent value\n\nFor cases where the required scopes depend on the value of the requested resource you can use a\nfunction in the `authScopes` option that returns the scope map for the field.\n\n```typescript\nbuilder.objectType(Article, {\n  fields: (t) => ({\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: (article, args, context, info) => {\n        if (context.User.id === article.author.id) {\n          // If user is author, let them see it\n          // returning a boolean lets you set auth without specifying other scopes to check\n          return true;\n        }\n\n        // If the user is not the author, require the employee scope\n        return {\n          employee: true,\n        };\n      },\n    }),\n  }),\n});\n```\n\nauthScope functions on fields will receive the same arguments as the field resolver, and will be\ncalled each time the resolve for the field would be called. This means the same authScope function\ncould be called multiple time for the same resource if the field is requested multiple times using\nan alias.\n\nreturning a boolean from an auth scope function is an easy way to allow or disallow a request from\nresolving a field without needing to evaluate additional scopes.\n\n### Setting type level scopes based on the parent value\n\nYou can also use a function in the authScope option for types. This function will be invoked with\nthe parent and the context as its arguments, and should return a scope map.\n\n```typescript\nbuilder.objectType(Article, {\n  authScope: (parent, context) => {\n    if (parent.isPublished()) {\n      return {\n        public: true,\n      };\n    }\n\n    return {\n      employee: true,\n    };\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nThe above example uses an authScope function to prevent the fields of an article from being loaded\nby non employees unless they have been published.\n\n### Setting scopes based on the return value of a field\n\nThis is a use that is not currently supported. The current work around is to move those checks down\nto the returned type. The downside of this is that any resulting permission errors will appear on\nthe fields of the returned type rather than the parent field.\n\n### Granting access to a resource based on how it is accessed\n\nIn some cases, you may want to grant a request scopes to access certain fields on a child type. To\ndo this you can use `$granted` scopes.\n\n```typescript\nbuilder.queryType({\n  fields: (t) => ({\n    freeArticle: t.field({\n      grantScopes: ['readArticle'],\n      // or\n      grantScopes: (parent, args, context, info) => ['readArticle'],\n    }),\n  }),\n});\n\nbuilder.objectType(Article, {\n  authScopes: {\n    public: true,\n    $granted: 'readArticle',\n  }\n  fields: (t) => ({\n    title: t.exposeString('title', {}),\n  }),\n});\n```\n\nIn the above example, the fields of the `Article` type normally require the `public` scope granted\nto logged in users, but can also be accessed with the `$granted` scope `readArticle`. This means\nthat if the field that returned the Article \"granted\" the scope, the article ran be read. The\n`freeArticle` field on the `Query` type grants this scope, allowing anyone querying that field to\naccess fields of the free article. `$granted` scopes are separate from other scopes, and do not give\na request access to normal scopes of the same name. `$granted` scopes are also not inherited by\nnested children, and would need to be explicitly passed down for each field if you wanted to grant\naccess to nested children.\n\n### Reusing checks for multiple, but not all fields\n\nYou may have cases where groups of fields on a type are accessible using some shared condition. This\nis another case where `$granted` scopes can be helpful.\n\n```typescript\nbuilder.objectType(Article, {\n  grantScopes: (article, context) => {\n    if (context.User.id === article.author.id) {\n      return ['author', 'readArticle'];\n    }\n\n    if (article.isDraft()) {\n      return [];\n    }\n\n    return ['readArticle'];\n  },\n  fields: (t) => ({\n    title: t.exposeString('title', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    content: t.exposeString('content', {\n      authScopes: {\n        $granted: 'readArticle',\n      },\n    }),\n    viewCount: t.exposeInt('viewCount', {\n      authScopes: {\n        $granted: 'author',\n      },\n    }),\n  }),\n});\n```\n\nIn the above example, `title`, `content`, and `viewCount` each use `$granted` scopes. In this case,\nrather than scopes being granted by the parent field, they are granted by the the Article type\nitself. This allows the access to each field to change based on some dynamic conditions \\(if the\nrequest is from the author, and if the article is a draft\\) without having to duplicate that logic\nin each individual field.\n\n### Interfaces\n\nInterfaces can define auth scopes on their fields the same way objects do. Fields for a type will\nrun checks for each interface it implements separately, meaning that a request would need to satisfy\nthe scope requirements for each interface separately before the field is resolved.\n\n## When checks are run, and how things are cached\n\n### Scope Initializer\n\nThe scope initializer would be run once the first time a field protected by auth scopes is resolved,\nits result will be cached for the current request.\n\n### authScopes functions on fields\n\nwhen using a function for `authScopes` on a field, the function will be run each time the field is\nresolved, since it has access to all the arguments passed to the resolver\n\n### authScopes functions on types\n\nwhen using a function for `authScopes` on a type, the function will be run the once for each\ninstance of that type in the response. It will be run lazily when the first field for that object is\nresolved, and its result will be cached and reused by all fields for that instance of the type.\n\n### scope loaders\n\nScope loaders will be run run whenever a field requires the corresponding scope with a unique\nparameter. The scope loader results are cached per request based on a combination of the name of the\nscope, and its parameter.\n\n### grantScope on field\n\n`grantScopes` on a field will run after the field is resolved, and is not cached\n\n### grantScope on type\n\n`grantScopes` on a type \\(object or interface\\) will run when the first field on the type is\nresolved. It's result will be cached and reused for each field of the same instance of the type.\n\n## API\n\n### Types\n\n- `AuthScopes`: `extends {}`. Each property is the name of its scope, each value is the type for the\n\n  scopes parameter.\n\n- `ScopeLoaderMap`: Object who's keys are scope names \\(from `AuthScopes`\\) and whos values are\n  either\n\n  booleans \\(indicating whether or not the request has the scope\\) or function that take a parameter\n\n  \\(type from `AuthScope`\\) and return `MaybePromise<boolean>`\n\n- `ScopeMap`: A map of scope names to parameters. Based on `AuthScopes`, may also contain `$all`,\n\n  `$any` or `$granted`.\n\n### Builder\n\n- `authScopes`: \\(context: Types\\['Context'\\]\\) =&gt; `MaybePromise<ScopeLoaderMap<Types>>`\n\n### Object and Interface options\n\n- `authScopes`: `ScopeMap` or `function`, accepts `parent` and `context` returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `function`, accepts `parent` and `context` returns `MaybePromise<string[]>`\n\n### Field Options\n\n- `authScopes`: `ScopeMap` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<ScopeMap>`\n\n- `grantScopes`: `string[]` or `function`, accepts same arguments as resolver, returns\n\n  `MaybePromise<string[]>`\n\n- `skipTypeScopes`: `boolean`\n- `skipInterfaceScopes`: `boolean`\n\n### toSchema options\n\n- `disableScopeAuth`: disable the scope auth plugin. Useful for testing.\n","readmeFilename":"","homepage":"https://github.com/hayes/giraphql#readme","repository":{"type":"git","url":"git+https://github.com/hayes/giraphql.git"},"bugs":{"url":"https://github.com/hayes/giraphql/issues"}}