{"_id":"@baransu/graphql_ppx_re","_rev":"109-b359ef755bd36f504adee9e05bde0485","name":"@baransu/graphql_ppx_re","dist-tags":{"latest":"0.7.1","next":"1.0.0-beta.10","dev":"1.0.0-082fb4d.0"},"versions":{"0.0.9":{"name":"@baransu/graphql_ppx_re","version":"0.0.9","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","publishConfig":{"access":"public"},"esy":{"build":"dune build -p graphql_ppx","buildsInSource":"_build"},"dependencies":{"@opam/dune":"*","@opam/result":"*","@opam/yojson":"*","@opam/ocaml-migrate-parsetree":"1.2.0","@opam/ppx_tools_versioned":"*","@esy-ocaml/reason":"*","refmterr":"*","ocaml":"~4.2.3"},"devDependencies":{"@esy-ocaml/merlin":"*","ocaml":"~4.2.3"},"peerDependencies":{"ocaml":" >= 4.2.3  < 4.7.0"},"gitHead":"d985ad80893b283623fa573d784dad4b74b1c342","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.0.9","_npmVersion":"5.5.1","_nodeVersion":"8.9.1","_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"dist":{"integrity":"sha512-vMu/a+a/T3/zUIqjg97XijdndVfDRFm8swPZrWNlgtRGSWmf1/2xPFiEgKSvsJvqgMppYosIBtKKLiDcIVt8vw==","shasum":"f68f03afb189979d5a02cd4513b4d99d05e7533e","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.0.9.tgz","fileCount":7,"unpackedSize":5924,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTpdyCRA9TVsSAnZWagAA8DMP/1ywGyNPg2Gcb/wbdkk4\nrFzS/F3J3cKKU7vd4CzrsbGABMcMNE/9xdL7kHrCdfAaKbYAX8L05wTwMq7W\n61ayZ9CyE/1qsSRwiOPmMUZFo9m0mu+3I4Q6vERlygFY+CfQHxgwujQ67poT\nvsRmJzVQUaCBB6r7BPEh09ywbEawaDJWwTeiMjcxM/r1bV+OYtRlvMK7YUcw\nu7JxHtu13/qrc7VBj8XkLkz/j5BQ2pNPgoPo/gUa9+R0FfAhHCAyM0yGauHp\nmE92CKlUWwccLGOKqJBbpwVtWTtBb4iop/7ShtsrGvu1gvk9H+l3HvubhMuE\nBlldHJmSTB+Yvr7BIzX/kYTe1MvbIqYVH3jvnILZCM92jadg4CzcMBF8CutE\nCD0WEg3h11AX2y2l1vdEJ9JT/Vam2Lo+OpN9+V1HvySq7HlHsPb00B0s5rxx\nyYtN0OgOXutKkHb4ixGy4q9wAyj0QZ9TiNljbr8HspFkW+F4NHPw6E2VTcat\nxxp5e7J162lTf96RrbWsVGtxziY3nfEouN940MLOIuVAYXSkeeolPxzD8P/P\ns1rA+/ijWqsJvvf9nWhT/NEJ8XmTlBGPzD7Yyjl++PIvM+I2Ji5Vve/Q2uzI\n+c6DlFbfg0ARgbQRbmeA8c8p0XDegV/2gFpXuYzfd1lD23gFu4D00hDiLeev\nTOOt\r\n=h+mW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAJasBnylgEW7NohEoJyVv1kjKUoVQ2ML/Rwsc1IWxfWAiEA6c4qcKuFlPUAeuLb80pIyMlKiVFDK6vDhKmMLV5e/vg="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.0.9_1565431666241_0.3835767527986629"},"_hasShrinkwrap":false},"0.0.11":{"name":"@baransu/graphql_ppx_re","version":"0.0.11","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"dune build -p graphql_ppx","buildsInSource":"_build"},"gitHead":"f0c5797594d0334f8f21091850cb6b190c7a4c1e","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.0.11","_npmVersion":"5.5.1","_nodeVersion":"8.9.1","_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"dist":{"integrity":"sha512-pjELVI6HN8de4cqUfZRr17YIwCG5D6W3HztrjimZpSX5wXVFFqq+75H6o7eFxojIvmkMQy56Vqh3hD1vg+fnag==","shasum":"7f172f21e89e220cc01637d40d8f1fe9c9aacdf7","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.0.11.tgz","fileCount":9,"unpackedSize":7477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTrJxCRA9TVsSAnZWagAAC9gP/38Anz5IeGsF8OUsDGX+\nvMp/eUIqEGsYw5EDnwIu4uQTXlR1S8D3BPAciEXzse39Bnj3unvwIMvE2HvJ\nsA7R66a4T3nDiuhJk/i+6b4gCNogIelvjCNK0XMQOxHavp2XDld213BSTfSC\nJFjfuBT818QWyQKdMMYIs4XkmFDEx2t4ZnEySU9DEjXpIwtg41i18KxmZHCj\nzxHnAYAG9iGbKH4kT/wNASfq98tH40bV13RNIo8iaBNt4GMRUEfb2JWKGIb9\n3eT0sZ2hziNkbbk5BruZLwBsJzkgTc6vyxdVgbF9iSMNYXIWluwkGJ7mPLAD\n8J3E8lMvsR/s0xVhPx5UhGULQyOo9t+u3htENtP3tcZHIkNnT1tgXD3MGYeD\nitHboUry9/9xE2rpcs5KGn2LnVPStEETIs4FLZRjCVcuxP3GFdgsMprdCgCj\nLAwAf62U5qUJ48aDgUdqggoIgkT1dhLM3EhP8D4/NHuW2jnL426FW/Ke8bNl\nJY9gESyobtSgDO7uyIvuxP8yl5gIpMXEekQ9x3P/rlHnii6pS/KUWYdljo0b\nsJmJT6P1NLKKb/C5WqoA+43NIzNBNAnkNmt1NxIbUuTktNDwZ19TO5Z6PP9n\nItjB1ituqYaJTLdNfvOFIowx0xQjhHmQeG3geU9kI6ZXV3apzuoe4Bum/ECo\n0EzH\r\n=qiXC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGuw1cQ2IUkauU6rh7eB8qPXf4p4rRjRRnjBheip9cnwIgAN5z3kxA1ssed6LYHbg8VDd7y75DNdisb3mvzzCPo7I="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.0.11_1565438576503_0.881381435881613"},"_hasShrinkwrap":false},"0.0.12":{"name":"@baransu/graphql_ppx_re","version":"0.0.12","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"dune build -p graphql_ppx","buildsInSource":"_build"},"gitHead":"d718559a6bc345d3045d09d959365d8baf5fa4da","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.0.12","_npmVersion":"5.5.1","_nodeVersion":"8.9.1","_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"dist":{"integrity":"sha512-K3fPeDSv26ztbEbwHbVTQxvnbntEJrQshbPWjQU1H/LzycQbkd6tfdZPEZfWb+ePIfd4ugEQHrwUx5elHsKhXg==","shasum":"e6aa4b62a7f2fc6db64f27ef2dce0ce3eb7d38c5","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.0.12.tgz","fileCount":11,"unpackedSize":24159514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTrkzCRA9TVsSAnZWagAAZo0P/3xEslzNBqjfs3O3pFOt\nnUiXQcOhL4KR6Gp7eT0u8q0q6g9fm6MeoDUIMzdI7FWWHKEpXtl2Tvz8MJCn\nr1sb3w5aP5j9T6khWZ5zXz6EbU4EhmDYqA8/Rfb4loV9U0osvsCEmeHlARFW\nqPuA+WzHEgClbiSPbDwk8080Az2gbqG3OavXImftYW5B60EYVKWAvDmKmczs\nvuL/4eUEnO+xi6ZE5S0PbkQaH01N/5wkJQuy/aONvc9PPpmGpKV4D3WPVjYx\nTem2lIozNH6BhRO6rP3esqFBAvr6nsy9JRMwebtj0qQ3As6qQ6/zndeYOVmp\nKfZ95yPz1s4yebGKRaV7rlu37pVtVAAPGRlq17Cpdh/DEbnKfLyneXFlgQiB\nYosfnlSJwv3G4+nhHiFpA8O+AsAqU3TpOTpssOGTtYvlVXQ8Zu4SSLJst4bR\nK/0N8NAatD3Gwu1RjQLNYgaYH58tfgSoCNT23M+WuBPVCGipzSi5TgRQJV12\nsGFDj4GqXAa54dTwbZpSCcaYjfuZ7B3tx4gcfYRJoxlBiMef+xV9+Lziv/Ki\n3Usjk/UqwUc2as/E3fz5cDk4imYqcgb2BYqcNuvh7mC0FdUZA+3KOtaxvyyv\ns9N0u6COrm3BFDHR1DhGgyW+clUBmuHKmuMg68zgsYRJZHqjrKdP1s8EALuQ\nIt1N\r\n=zd+n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHqnqNB0N8Nrnx+ws9sZowty7nIk63kDZXmf3cqCQKXgIhAP7AW/AsFhSZAPUvBpTG7riFYUIeO/AAC8rww/na40ul"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.0.12_1565440307031_0.7683748778303441"},"_hasShrinkwrap":false},"0.1.0-beta.1":{"name":"@baransu/graphql_ppx_re","version":"0.1.0-beta.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"dune build -p graphql_ppx","buildsInSource":"_build"},"gitHead":"3697fe43e3a8969fecab4a07455bc8dc9b0c0e8e","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.1.0-beta.1","_npmVersion":"5.5.1","_nodeVersion":"8.9.1","_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"dist":{"integrity":"sha512-/eVCfjZ96VN9icw7gCQqIk4uaz1Yy0QXGohoF+2Jw3W6fvpOuH9gFcnizDwEs1vp15T73I5kCZ7rpRgZ9SUCqg==","shasum":"b5beae08feab775dc753bccfbcad3f9f048d4f2a","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.1.0-beta.1.tgz","fileCount":7,"unpackedSize":24158001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTr9HCRA9TVsSAnZWagAAzy0QAJWf4JRkbJS+TSf7Ca49\ntwoVt+O/29DuBS1NBdQlXZq6EQ6e7zuzjnt0rXvTXBbZLgzLVx5Do4rQF76S\nx9MsvpoWm1jpNz4+2wM4b8TvqDNywREq0SUs8FtfexCPT6nk3pz3w3Wfysq7\nbFdkI972uA9gmHx0vmgwbqocJaxzTzzX0XzaOtVjPIESEzYkoy+zyEsdT0JH\nZrYVs1q/2hjbrNZ3jf8aDjzbJ3cliRKAf3DLqsOhab6+VAhU/eAlXvRfD14J\nBGdiRdbsDuddZ1j1YiCRl3ikxcDFlmMnOrqfofc+0iWfj4nUpzCXjOmEmzko\n7UluFwsy1theYyCStmaqxRjDCLVsqBenayAYCsuU2mCYkbZbDh78dME7fcVK\n5/tx5NMUaN3dgug6t2V9s0l/pT8h2OrbHsheD+oeTx7TH86X0xbnSDojlDbc\n4ghYhRWScUWSwUPIGcirgZpfCcK3Rhqvrf1203ssyH49dKPUZqPqfCAdIRYM\nhfL5Rl7Ygq+G0XNTOsbKJ+9EdNhWZxPT3R478GrPY5FOKTsVe/jV63gpEYoB\nvZ6kZHvP4e1EWsxe0E0Lua+3IXyA2Qh6gd2wF0L1BvA2b+cUPhY7Q4QLiKqY\n6Gfi3ZtvPAiwzzIo/Pquvoov5I7r9JjBXNKvNws1ydx5bMS8cy3tlH8ncEHc\nC9Tl\r\n=J5h0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqPf0RbNk6odgh9gAzGWRsY1HHd2680V/q9tVrpOT5fAIgev6PyVvM+BARNWvwtF+qnsukrl6xU/KIx+gbwfMrW8k="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.1.0-beta.1_1565441862588_0.4203635006267987"},"_hasShrinkwrap":false},"0.1.0-beta.2":{"name":"@baransu/graphql_ppx_re","version":"0.1.0-beta.2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"dune build -p graphql_ppx","buildsInSource":"_build"},"gitHead":"4899e2825f9f9e6b3688f29647b58a1a4add87dd","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.1.0-beta.2","_npmVersion":"5.5.1","_nodeVersion":"8.9.1","_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"dist":{"integrity":"sha512-hrMzKh9uN2Ju5trjkWbbdsPFIwxUhfbFq2S9cCqFTyPz5fbVDTTjufzdiMZIvami01Ns6FRZjiYnhNaluClJvA==","shasum":"7b46d2ba1f54fb5d3b65fd233d34ea53bc3f98a9","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.1.0-beta.2.tgz","fileCount":7,"unpackedSize":24158049,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTs++CRA9TVsSAnZWagAALPwP/2nl8q+H2b7Fn+AaMwRr\nt3uU7NI8naecHsw3/nVJJmAOBLVZcD6Ep7WQMiAC7Q3s1xcBjkpreIxcNh3d\nef1YFzwcvlNXWt6qRYgIkw03yo0EcB77O/W6y5cHv0qgJ+awvlC68zpT2DpW\n/FPVWlPhZSj6mOGXvK8LC501wVMx4y8jy8mSVLtssBLCckxIpPQ4N/Xeb6/N\n5v/Xn6ICIEJfFLOlgvSnn4GvmxPe6EXZe8MaxAPelWEJ0IsOsvE822ej88Ut\nnyK2bR/RruZPgMtv+6gqkvpgnh/kp/PIaHnLIYh83vDBWtrfOGgFxW44ms3R\ncXLPn/rZ8kd8n90g1nBjM28YljdynhwHM/7JlHk8B9HrCn4acDWGL2T1ddbZ\n6fogsiiaMZlQRaFbhiuLVPLQWOJvLmcQr52b2a+vwXoqkf1Sf8+Nuj1jsJDX\nI5I0+v1vGeIHzvRahTMIBnXBw/0YGaKcrWWmk9aE+CDzLo9fLfudKfX9R2OC\namguc3nsb6Ts948sTW/AyfqH0RFs5bI+mrRMpy+LlSqD7SGXQqnTm33uZ+Sr\nNEWSb8UjGdm5iULcVfiNBNaZMM21o/VL2Ph+QwpKUw8i04fsS45+4ZftXmsa\nHVfAQP67FyyCezgrlPfUBca7hxRQdhByCXqiAvGuglEB76JdXdKVLDGSh9uF\nIBht\r\n=zW9h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBq8bQXeH2qA8njzIpU8+NTMNpoqupSGyf3vYDgbF3C8AiAt2JsFwR8/owiNqQ0EzvyqXsMbJg4jIOHCSOAlVq350Q=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.1.0-beta.2_1565446077735_0.04593461488397432"},"_hasShrinkwrap":false},"0.1.0-beta.3":{"name":"@baransu/graphql_ppx_re","version":"0.1.0-beta.3","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"refmterr dune build -p graphql_ppx"},"gitHead":"0db12be1cef0239efb89048db90d4f04981f7b66","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.1.0-beta.3","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-J60o82eFNg0bad8iIOqRNq8jrwPiJbfbswJJkd28Fx/L6GupEviD0cccbQZPZV+yaEGrRd8Bcv90aR3LYouGGw==","shasum":"1d712e8f202f8f57653227d1988744247edb5d2d","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.1.0-beta.3.tgz","fileCount":9,"unpackedSize":25543361,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJddjW5CRA9TVsSAnZWagAAzbcQAIrQjYu+C9aNcRSD7BuJ\nhDbZ3Mant7gOFpK4d09OIIwLlwyiiYosZpWj/dr1cUv3XH20IDHZT2XWRtBY\nxQ3ZjIjKAhbqSv5A7/eRYoilwMRxEe+JaCG4LOEu7YzanlVGTZqmpxZTQAEH\nf/g2FAkrx6wtOytEdaSxTkeYPXA9ASrd5F0vz2YdbFHz3RbBtpgfjhw0135L\n66vj+PiOxlBJqQea83ZBtA7jgL7M+3yuqYQZ97Ubo0MmI5wFAM3eOTEehQIL\n9f/7vU27GRpGQ765AUF1ElXsGrTjl19v6LU35x/L48bJpvzpQ9hOTqSIfwyr\nVEyit9k0Kc05sedkbYZBk7JghQM2D2nyK4bSgmklD+dq+00sOEHsONjspKbu\nSKPKAn7X+2EmZTvVuHaaeq/m+BwXDW3zNe2ydyhP61zzmdkABev/U50WB7ix\nU0Ysz4Aa1yJms+TYIqGcyDfsWSkMVGK/z+l4/FjmouZG89y2g/lkvuEiMhRs\nMXc+diEPfibgTVpeUYZNtT1LM4r0JR3bu8SCY0X2bKBKlNTUXtv+B52cR5u/\nObghNOIL2JYHsqkCDCmclKh5+4LW+SkMJUBDw/jtaPhECer4WOlP012ylDgp\n/m9Gdbc/2B91dy0NMlfdUgC2XKlrFoQKrsFM5iTaA/CqsCgo8yYtcoNfqksq\nPG/N\r\n=K0YP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID8Vi2IjxfmW2Xzc7aOP30LgWlr8hm6XfmDQPkMjfb45AiB8ZwPHyRiVf/HhSF8RI0KnnMvh6n1uihTO4eRbfa7iIA=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.1.0-beta.3_1568028088216_0.16266242086540994"},"_hasShrinkwrap":false},"0.1.0-beta.13":{"name":"@baransu/graphql_ppx_re","version":"0.1.0-beta.13","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"refmterr dune build -p graphql_ppx"},"gitHead":"409ad9bf79fc97fec4f5731214f4240f00e258fc","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.1.0-beta.13","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-GMGe5IX05MmL4yafEbhOYYFp7MKWHEWkK9lbYr/nhvMLclH9FXDSrEaNtDk8Lffcgw/hsYXaa/X1RIXpzCkN1Q==","shasum":"f57edaa5b745fcf48cb446438dd6a45051c3c24e","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.1.0-beta.13.tgz","fileCount":10,"unpackedSize":37015175,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdlJfbCRA9TVsSAnZWagAAmMwP/1bQQpxTB1zSqBhqOuMV\n3rZVJpN3gwuz6+r6GTkJYe3Zd7cJeudA/u1izGemJpOS6hlUhCBkd2JNX85i\nt4dUZKA2FzYsA+/ufsW2n+sRhTE/bhtxP+/B+Z+Gac4Ha+Hfe6TKeJcIQJJJ\ntAeNwHHiiPY560eUm8yXfPMLrc9k6+6zdgnHD56OJnvMFgyy7MD8JEDhR3T6\nvdTcmoYezU5xdY6KRUR0EBJLZjgAp6FSUSqbLg3kx7NNxViXb87fTexlO2XS\nDnr0EPFAm1pFSoC35DC3yfSx3kIPaj+z/sRKEO6iIh9eKBxWrVf8OGB3V6p0\nyKoz6lZETZhk+mUwnyvN4t663w/wqOekByt7BBCxcvdvoX1ViuusmAwS2VFB\ncUfLX1QWctuLN3T4DBb5YvjAIQqLT7HLNP6yF+mb7p5URDZQuJDX7ADpZ6Ez\nS4LVGU7Z2a7xsUC34kQs8i53BKSOjWw7pE4d6MkW62OUmeQXCkMC7FfaWvov\nCWSAbCba6yAe0g6eJW0oliA/mb1vyCVEUke6shK9+VU+TpvKf8mxyPsfpCDL\nmIvqZaWSoI9IqpoJtWThIQYvUvC+33/snZTv9oPa1qJd5etD0Fk15oQxE+xg\ngPKf/EmankrX6lLmF/8zx24Gl2Li299TOZRhthpL4tX6JiefYds01dAzf1LI\nzmIL\r\n=RXj5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDer9MSb+4UaytWMsrAtJuwsaUcvFkPFVXvI231/712LAIhAIU9v5i1EV7lE+RcrXX1wTuTvkn+gANdyWfCPctY8vLC"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.1.0-beta.13_1570019290250_0.9363438759236156"},"_hasShrinkwrap":false},"0.1.0-beta.14":{"name":"@baransu/graphql_ppx_re","version":"0.1.0-beta.14","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"esy":{"build":"refmterr dune build -p graphql_ppx"},"gitHead":"7f04bf85e62c5751f8b0e0d5e6352ce4564fff3d","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.1.0-beta.14","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-jGJ4bYZrOA91h5DIqBgku3wOe8HWbjrJSk0XHnIIx0eiVC9vBFfZLpLW4DvmKzrVGyTGBJZfKVInkEpB8vAQdA==","shasum":"2de4cb971da8062b5e2302a2ce79622f77ef0ffb","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.1.0-beta.14.tgz","fileCount":10,"unpackedSize":37014995,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdlwYmCRA9TVsSAnZWagAAOjgP+QFEJp1IE4mavIt8pjqu\ntK7++6GX6HrpnwXpklr9gIp/+OCa5m/dOdmz3WsgXKp/LBr/TWj1X0ZrWt8i\nfXGhKY1fS44XzMV9onV5jNap2LShTv084gd9oXYYW6CpXhzKC1ynsfs7C9Tk\npdXhbz5+vEv+YCFAR2MjJhsXMbu+6JkWAa4trEi4aHyOpqiYp2+lJaSXQXGA\nJRYXoFSCbUuiwv1TK3jla/N88CQKRLos1/Xz0I3eIKvK10cEWmiGNpzeLswI\nuRO3972Yhs2yp+vtx6XggQkbD/9ZuK6KTfCnjVK1ES2Ldoh740XewDAD5N/K\n1I4Uj55HOfrBlceb7m/SJOYmghgTB+v5oyDJSMnidD7f5MrNzA/xWgGjtA0H\ntdu+Jxjvpz8KpuerupOVimqK0IeRQ4e9zXjG2isYJhUUnUSDlnB6jTXzhYpG\nLKUkNCQgTov/ghGfd92AGFPYWYNfk+3jMKZExKYjSsBXC3zl8oQv4eJi6spT\nSTUigJh6UEJm6IooPq+A1GCXjxmV/WuNnAEEDiJHVZSh4HkUddWKqodMArJq\nsKf65G4aHODTozNSjXfHXRnimTd68HfhuL2//PM0GZRlxUCM+fCR5Ergs391\n2zFH41D6u/GVf2yyVdP+EzBWxzhY0ZsONgXU2NGi03nmnqFks49TElyE5L4j\nG856\r\n=nbba\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAoM47agTceynOfEJuxaVI27szl98/3rKQ6zgY5r0KtAIgATzGtdyjzvHD/CHhoQLGQRne1kRE+HTdZVvseQLnWZE="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.1.0-beta.14_1570178598055_0.6797732394769231"},"_hasShrinkwrap":false},"0.2.0-beta.2":{"name":"@baransu/graphql_ppx_re","version":"0.2.0-beta.2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"e32de525d74fa3c0027e9ec6733abb00c204cd50","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.2.0-beta.2","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-x1XfYXMBWUDz2+/3J0ns3D536XH/mKb1ZPUaNUv2L/dDZ+Y4b4+yPjyiYnOvOyw3iGNb7SaGkRSfyXtAcTfOPA==","shasum":"7a54c7d959cee7a207c824a01581a203a7a2eed9","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.2.0-beta.2.tgz","fileCount":93,"unpackedSize":82814984,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdmQqDCRA9TVsSAnZWagAAwZsP/jQz5ikdxEnnfwtveZOA\ne/8bVd+VUqixyu4a7smI6RrLiyLuAV3DnajBpb7Jyp02vgTPgRXi3WGeldAZ\nf7AnHH4V9QGcOsrlmDVDAe1vdkRHcHpQLEJrKIrOMbEIJXtsSPsjOuCOKjei\n7QulatRqgxE7mwlDrc0cvus0/d/QjK0k4od3TTbVm/B3U8f3d8t87uamJsBW\nJ1idDSlCWs9cHRXg0q3ROGD5u98QZduMQ0HRUFQiQKhsDpv3ADLcdlpJBrI6\nQgM3USy9nYiUBjMhpNO1j0C23BPW8JyAiK0nFE918TbHKVX6K9D+Pe5sM3w9\nBKxv41OkUU+JsYPY2eyh9OVO6NBKkEzlNQPUy4aTAdQYGiDvuEVoYV+cjpKn\njfJ1t5Ed6JjxbUHJ8kKeO6L29atjYefOoc800qiN2WhXHQYRAyqyTyw3rldo\n4CllYYUnDPsYVkwFVtVxMkZh47o3WqX8wCpa0uqYUIWPcNUjlMFuy1KQkyeB\nHqW+qr8+fsropac+d9ySlPA6ew/cO9a5Oxw6lpR5cncz7XFSzZLcPiI5tFMI\nVFwBTEeGFjr7IFBYk5KJ0IO6NuHv32irjhWNJ6d/7Ws4LmP+vOK6twOf9szm\n4bGu2TySSMo2FTPDINWhLcPfTbmsKYRM/gFzC0b9/iAD3hHLtdj6u3wbtJOZ\n6f6H\r\n=4jj1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCcGcZbBxcwURnyuhRSOMOMkKkYe/6aVGoRpwbjrvmWlwIhANX6pWxQN9vQlbF52z7cbtYgc0ndjiyWWhVUPcIeRkZp"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.2.0-beta.2_1570310786622_0.5555806982762892"},"_hasShrinkwrap":false},"0.2.0":{"name":"@baransu/graphql_ppx_re","version":"0.2.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"c7fab6cad60822655cd29ad7f9ffc7b59639f9fd","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.2.0","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-g7SFvYeEDOS1Pix+B9i+MWNk0vPeqX1wNxwXjpG5YoaFfX4Bo5T+Urmw0gHYmBIULMC5DaKftWYdrsrJg08ZUA==","shasum":"33ff1a71a5bfde820abd0a328b449f04212865d1","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.2.0.tgz","fileCount":94,"unpackedSize":82853519,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdnGZgCRA9TVsSAnZWagAAhtEP/iG3dnAtz1VbazgfsI7h\n3VWX67rs2VboLZ54K43c+ScCKb4oU6hCW8URIGrvJyxnKds/P+GMgIcVz1/0\ncfPUxl1welb+/O8xORkmb4IQ2PDVCgsRIRShMOKvNKvCBZhuhc+hkUxMegVC\nxdoU3pWZ0+VK9jNLqvWaPdZeJ4P1+hO3DuYVUJTfSLMIq9byPnJKiiEZxRUj\ng5Jxj6okvC00ibP/LdJSGKh1nZFlogAaGMwYnm7BertvQzDCdDVnMJSgRjoR\nG95NuemIEJYsouirKgVPR1P9CFC8F7EYc94qs3uNhDEx0zPIEr/5jOjIXKuw\noVojuUXGiD4m6kKAbL1Gox0OJk1cLIhKF2yNSWzlIeKv3ST2YKCMVmCw9cKo\n6AdiCNfA/dnB/o8+SLiuRQsBHS8lRO6TyNgHqhl35myJNkpZSRY794V1cuSa\nRQpsp1cwZTsfIyfqOibFAVhWeTJpwoBWoo9kPglliHg9deecAkwP2+WDz26X\n7Mp+olPXzspj/3cx+00cpMzV/edN77WBUPJdDYINL7zte36nrahLZfcCuufc\n+FVB9U5k49dvWJBjGPUxRK/VDP+mQ9MRZHU8cShW3WbQ/yJyIsAH++OWRtNJ\nuS3faA1eTmejP0J4P09TGF/PcDSsj/+njiqGXMxZWX6bV+DXaclNMKYnsiNW\nE4Zx\r\n=YZRN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkbsjWl5SVOdjDkU7hjZEgXlhoBTMrifbq3Ssu5IrrDAIhANZsX2FUgwXF1Ao+3lMn7IH00uyjtJ36D7I2M65BDbbF"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.2.0_1570530911365_0.1253381589859226"},"_hasShrinkwrap":false},"0.3.1":{"name":"@baransu/graphql_ppx_re","version":"0.3.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"0b2b4bdbb1f74a1f22f1ae4f55bf1edbe39b29c9","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.3.1","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-PSYXkJ8yGLXomR8+nCW9elsElO7LwM9lPB6OtmCi9Se1JyGagI+/OIRDmiatR4gUHRcGkeWBWre1SeerRzAkyw==","shasum":"9b0741bfd4652ff7f33e2d75991517fc67e5ff03","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.3.1.tgz","fileCount":94,"unpackedSize":82871719,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdquYUCRA9TVsSAnZWagAAjl4P/jJ9/Si6qAsqJwb3fyAn\nkgduPgQ1lrNPg/TkPM/9ReU5WdUzawZGagn9yP/s2M+8mCwxUVbzJPsG49CN\nTtD3fUVf0ZT5cnQIbgsTCoV0ETbSJ8Ni8XW2N1O9tWKjL/Q9R4nKqDlr76XB\ngh63gZKoNxWA5He/I2ZRDI/rsNCVJTF03vAA8NvFY7V/UqLDs1jPaZlAMjPb\nF2vfXOQOCwps7aR2tRw7or4LY393PVohMR94O0KLsF9BO3jbt+XYheMe+cYg\n3dMXMG9j0Kcs2GCl3Yfo5V66AuMteE0hQzSETfSh3GgaNa6N4f/YJzbpvh0N\nUjWeALhLyNsP0qF5GeUAPSSWKEuf2Pm/L7WqUEueH2oimmAsi7Xv8flRhzXC\nwZWeRPCwDEyai6nUmvW+8dFGr/m2KK0Hq2Dg8xEYHCw3nE8G83ALepoFgQaB\nyNf5iropS1zGXzNyDQfY5I/PNhXsdFX0JpeOuxel3xme2nh/0FpNZn8TVnc+\nekVyN+CXbTXznyZrkaM5VXijlksFA8kNsP8tveZx+YTZc+fwRN4YU0hTyp9z\nD2qrC077nc9LV8CzQSzNF79oRFbZjca32QKZXaNJ/F4s3b6Dl3bh0lOHNkyJ\nj0jCU6gh8I9wSkuCgEk3GzyYYgOTCgX8cbtVy1RIYt+dAKrTLSjoRDSF4D2P\nqpSk\r\n=N+5x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQChhFyhpGYPo90lOnlTtYoUf6n3MEXxGIs4v/TPRwfGMgIhAN/BuBvNKsdi0HnOl+TSE33mwRTntIMtHNhm/m/RQ1cl"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.3.1_1571481106997_0.6338188351391234"},"_hasShrinkwrap":false},"0.3.2":{"name":"@baransu/graphql_ppx_re","version":"0.3.2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"0344ce28df9218ba2b9c8a8f45edfb3a8910d7ed","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.3.2","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-DseaS4enJpd43MyTEQZagbEktCzE0wpI96QSxOYR9AHpkgLNrSaM92yi8FBV8Q4sYmFX9191Bdjp+30Y0KWXwQ==","shasum":"6876609be84853b1da6184b7868731066a892851","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.3.2.tgz","fileCount":94,"unpackedSize":82879653,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdribwCRA9TVsSAnZWagAAhfEP/1lj7KI7B0TGPxu621ZB\nDrofDUicdkyQwRoLiYdnp8RcqJ7UjPNgS5pVPojfm2xgXF7QDKfEp2X0eYpK\neimZpWmMnu1EEIn8yGetZTYiG8y7ygWzxor1MXJkD3DRLRVKj38yrUhSc5+o\nZLVjZWxlM46nsIbOClPsi7slvSF6FJnDYMZM4ewF/EdlfYfgAScySBTFmKnl\nKhVTHY2I5GLm6cS1YV/AUtHVj9AeSAvRTT4NWD/d87DkLoqOVnxfJFzgbMoa\n5nVRRipndXejNbU2eGKXRJvKG8vze5m+N3W1/gJzihzyoYaygLDVtOur0sby\nG3M6GIBMq7otxHUMLK+MGpPC+X9I+6inuz8c/j3/0ABErjknjSgvZzpSa7N4\nsay6C5gOfs3kqZP7MF0cWvACq4j3vUfH3zhCCp2zQISv2yukgtgF1aMJfiri\n+LpALHSGBgtRuU0EPdlpXwvBrwfYMfxC6HYk8DTsVirD2bQQ+bfzh3txpDpX\n8bZpmDMYUb7zFWDOWUWy5ug5PNo1ixmjHGlKpfpN3VktaUM9x4tmcEl8ZW/X\naPR9elSkTu3Wv6LE3VvXxtfcKW91GteDUq7Bkj4Nqfyh1eKbFGOD6vnFpQd5\ne2Jd19ZHbwJS7FKJsO8+14yRHB7WUvoRgIthxYfQjhzedYGOWI6bSPqbqiwY\nrHKR\r\n=O3ZY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDsvlWwBwcvJ/8cKpRwYMoW1PuLaPFcNKAq8TkNF4V/NwIgBI8EsSJQvXajWKkeiNNZE/O+4oCl7N9by6eHKIWFAGs="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.3.2_1571694319579_0.5977978959631214"},"_hasShrinkwrap":false},"0.3.3":{"name":"@baransu/graphql_ppx_re","version":"0.3.3","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"3d1ee106ded9ec954db347516525362722d1ab11","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.3.3","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-z6oEvLQ5Z5yu1M07YT5ph/HL3m1Q8pHlqsfbKi8YZ944pFo85ci7vDoYu9jrizqEJZZjWcAfjmnqmJf3ObnbOg==","shasum":"26f90ab24ccb21530d5e944a42e49c27a4f72691","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.3.3.tgz","fileCount":94,"unpackedSize":86686471,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd2VCMCRA9TVsSAnZWagAAR+4P/ietGprTU9TqzPm0mXPF\nWky3QM+uv0F8MQ/R6a2RDTog2KQAdahZKiAMbaQK9X4hoW1e6LfqOMKi8NRX\nO1e2Q04TkZSRjxXdAbJ1Wgty9h8y3lhmI1/ctu8uPrVBj3Z6xIahMBBzCRV8\n/Kue+Qhe0x/0ZH+M2jBdK5JrhzTz8KJSo4HTXK5TvZ6sYVV/RHfOHFDbMup0\noiv+K0zoAWA4wa6c+Sps1rgclHz1Qx8r7+25uzhH0sfhSTW1UqM4TbQJ2BSm\nm51O31gsyILTKH6A11tlvo8gnrFvP5Rf/P4KNvM+QaFP/fRtOPcWHv66XZ83\nJ08/gNLiuSahSMVepzLFZMqfHTjWzOAZum+zCNQl9ttVgibBy6ONo6gixspI\nC6Tcr1zZ4Y7oMmEe1detR30IdlhvQgFXk2wkgtwXHyCfKaTBM7YJKoG62fan\nfQebF2krdMe7MH3izm8RV1cU7/6k5KdxGlQnUgA+xcRXXWXyGHGeZ7jdZ/Ky\nNnk6Wju5+JmtNSRJ2+3Gi6lJE9Ox+0wUkmP03Ekk5SAQjmAVt9Tr8CDWA72w\n9NsGQf3SCes/htmY6p5PQI/TIOajs87SMe6eGJACTkkyesjbvlnROTjutvbB\nS9JPI9m0IZNwK5tlNspItg6wHxmD2MjY9EJYAcuAms3MWJiSHUC9eAGq4qmb\nnl+i\r\n=/t1W\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBPG/tW/ZTMD9wbLp+BnuulFRZh6mr4mcMWURdtORSsaAiEArVQlc9z5gdBrkGaeOqK9cfdAe5+HK0st8J3Hz/bFde0="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.3.3_1574523019324_0.7178687942684261"},"_hasShrinkwrap":false},"0.3.5":{"name":"@baransu/graphql_ppx_re","version":"0.3.5","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"e170c4b32d1df671b037337a69454c356485854d","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.3.5","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-I2CgJQ8AlkGtGHWKrbvO88CNXpS8sEfil3DOA+uJNyGxlOruIGvaiFj8Oa+ayBAljOqanEqTgeEm2ec2UMQJOg==","shasum":"d168d689df47f5c0c5d99dea401e24cdf0946fa6","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.3.5.tgz","fileCount":94,"unpackedSize":86700326,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd2W6eCRA9TVsSAnZWagAAVDgP/RKQCVZPy03GUxDbIwcD\nPv5TswvvMLxmvcJYjNT9C4FpizbHC9v/TaAzlWA0R+ouSomGtC4ODceC/9O0\nwoCZbm/EX0nso1vU9CEsQ4wqVNoX4jj5ECDBJ0g3CrNRVxxScpXkjM/hjc/8\nMW/rckzfdw7KCha77A4uMLr12W2WKDJkE08S4f0b5phH2chM2VVF73rEezmj\nQ6MyMwDtuAbc5GFPTwqe+RI5NU+UmgwdJI/jDcfw3XiTIZF920CuYxt6cJS+\nYTU6dlP9o9vLM8mAxfwTDCUyiwNcex4Dk7GeIi8w+vKfc6bgguoY5ezQhT3u\nkFtNnH+jMXJvBGP6Xc7x0C9e4e9TmkAbmumKsZV//jfcuHhbQ5yrF671NJEY\ngrjRGHNHWhgNALZuEG91aZhGVNrENXd9S7zuXc7r+nDpevd4pdxKsZOTNQrc\nuIbi1LUUPgODlrds3+98ZyZVK9u/XsTr5UxDkuAW7to0fm+QWpNVjcCI21Df\nN+i+J3n8pviDGzH/XyvQ2+A9teOwykl504FWrQneDxq58/lf0O4aHWLP99RH\n3yHc+P0rGV0g0DJIl7mdD7t10eoCtPzhNBZxyUp8NqsUiqQ3Zli7G7Iadhsf\nf3m44V5gInMvc6JSZxV41sNJePTfD0X1LV+4hnQT2i6sH0HfVHlLk+StMf0y\nf2Ce\r\n=Y3gv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFaMaEFwp9FIOPudAdAjyf7srQOvZyRWooExeRNFK9CTAiEAsnZ4IzACI7aMXjUFHUofzosZdAaMlO64bDaoR+O1/ys="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.3.5_1574530717538_0.12304607256386446"},"_hasShrinkwrap":false},"0.4.0":{"name":"@baransu/graphql_ppx_re","version":"0.4.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"6e1f30c6608d281e8e8323796cbafd1a199da5f6","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.4.0","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-vCWaBTbLRHDRvl72e80UH1Xo6Rp7JaBJgBgt24jBX1zXPdpvELObwxapmaSdPHK+wI31X0fRJu9z6yD7IAlBDA==","shasum":"24f01e19d030768bba85a8676c70679c8fb63725","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.4.0.tgz","fileCount":94,"unpackedSize":86714400,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd3CpDCRA9TVsSAnZWagAArbQQAI1fvizWNca5hurceJho\nNhAcuD+kWt8chFozJGhhn/y+fmcxgpickWHDDD7YAa6fq8z/fU6O7Jsq45pR\n9EJe8XoVuDUb3lfO9jvc9r33Lc86AW1ovzzYvRLXygQIm+tf6ZZUlqnapIGb\nSfuV5ltJZFMIBCeTs6JVtaM4tO7o++NHbH80XHUlpu2DIVVXTR2pApHK3+m1\nhsnkvWlwm9N3YjxOr/HEH/FjlQ6g1E8KdX/h1ypeEepAHhXVk6nY2jmP1RV9\nYu5ALSSIXRrV1yYswx7a4HWAlnG763kEMvJiSVelZDPIXqNDmQtYIqJGCzgi\npNrJBQA3UhLvpKXBMpn2EwHrK6v1Z38zjMp6gw4bE/5w4vJrmcFT3XMw88Nu\nCd4Vw/YREjGspRamXi3BaOiY7lT7PUZ4ogcTgFOjg2M/KiaKYqWqjHnWL6r1\nRerX6fEE+f4lDOWccU/e+GMAkzfZlqGOp3tuD4kNsFrqvAVvAcfndFLDMQU0\njmnxNFdMH0osmWa5E+IcSypyH1JPtXWoJ8+M9zuxm1Ry4UlW1DVRB2/s1lLH\nhVoznI6u5Udup1OLomTnRD1QQjh1pc6p+IsafIN/nLtDfzfrJ1O/u88MbEBT\nEGhVu/daRPbNpq80hqFT4ppnQMrYyfiznxLY3Cq1+FeMSYb4IaG8czA45GIP\n4goX\r\n=NCIr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZMkCTnSgGyk4xrVTsfxDCr5NYs9BbdRhQIBThX+ADlwIhAO4rBKaeT2zi4nbNc7yzEyMht85wkbJqvRkM3oiu/FUl"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.4.0_1574709826576_0.5983433857134173"},"_hasShrinkwrap":false},"0.4.1":{"name":"@baransu/graphql_ppx_re","version":"0.4.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"ac712f62160f7f3b3c96f5492509cfee825d91c6","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.4.1","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-nrpMYlOJAGJFXRze8lGWGADHtIB3qx2unL9AtKl8eOo6yfPrO94PKMmOTcamXKG0WgzuduOfivR6GVpxuNw4KQ==","shasum":"a09e3c60c6bf5791ca9f564ee65263011932484c","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.4.1.tgz","fileCount":98,"unpackedSize":86771811,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd66u8CRA9TVsSAnZWagAAjrEP/0dUpxVAYKdLvKudIHft\n13EVAVZ0aWmD2vEkxjtffc7J2DCSO3k2eLGMwZJBF+A7Fe+sd8kwMhm3/WmZ\nFxiQsHn5vyHeBCHrC0fF6Q28pjCV/M2BG5zmor2cRaYIhylm0TSWj7D04eQw\nDT1HHI0Xgh/RYnefKgRGF/TrstTtgEv4SUcnUGEhbwyy61qpe6U5Vb0SJzpT\nUGe3+UU4/GcnBvAtBaWfsYmmHfPQBP7v5NNl1fIt8ywgua8zlWwTFRjpuLZ/\ntIpjjh0zvqnbhuHZo6sLQXWMaxsp7vtC1iYRZevtBqB0PNkGtODwMQyPadM4\nnLku08C4hB8Q50dPIquXxlaH9djREX/gCxzDbZqQTljhLoz0vla1+/oRIGnE\nZtYEG+dg32unJ/oQ+g/LDwOtsmroK+HS5EODVqMJF4Ab5kec9u14efXS8GYm\nZeypx6nsFWqCS6SNHPy3PA7LN4EDKGOik7ZqxL/vHLWFye8pj03MBAsH9W0m\nbAhDNsS4wXHECJdc43bK3s8h2woontjWYr5Hn2fJig1sp9JJpBVAn8WE8lhU\n5KElpNhfYCXs8cxXdsC8RFIhbn1rbjb6w8Q7T9k+dqjhppCjsjyskgfvIErC\ni9c1t2/jI1KmqV54lMuYGA2OOatHs1iqAGTNXBvoVhcZzYAZEKUflc/65siV\nwUNq\r\n=Z7Dk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID8UoWsaQOxZT+p1a2T6NxMOCdFl2hWllUWGY16/EhKHAiEA84diuKFJFy/mi62Z3sYw6wgYBZE44c13SJXL8Ol1s2Y="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.4.1_1575726011680_0.6906072335463884"},"_hasShrinkwrap":false},"0.4.6":{"name":"@baransu/graphql_ppx_re","version":"0.4.6","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"27a2aea1ebfe7de64e4792d7ad9ff79968c97d32","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.4.6","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-BlVNBF4926NPdhODAdemGeCFsPw7HNWLo3o2kQM2kr+6XXrog86etwRN/2/4Xa8KUzqKWM2ohjJEbbZE/cIHyQ==","shasum":"cd4e20a5c5496a665e08aca0f4dea78ecca2e0d7","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.4.6.tgz","fileCount":98,"unpackedSize":86771811,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd67UnCRA9TVsSAnZWagAASC8P/jGFlcI3wz94RN9w6iRw\nbdfnTuMNPV9ELqUQ735A5V87yOXn5j+xGVLMLwHhzjCoqBMwbI7mXIJHz0Sx\n+9zFKco1gMVkApTv+0yL9vgQZ1a3pmedfcz/xsBJozjpjWflX6aSYLQtnA8B\nYujLCbZKfHl3z4nSl7PafuXafy53zN6DQxaFLaCzBmoay9Kv6ZWcwAQp5zqT\nw3DdPpYcGUZe+3rs4LZBRchHG5VKgZ5KXqqHJ/x5KY+a0ruptzn2iu6CBqNg\nSJkDzpleisMqu0YbbeeatCIjoc0Rd9YOnf2mewHTOlUNJ7mj7PjsJntyn4eH\nWD0FAFUkOBhkS7/mnU7bKOmYrwZo1kC5PkLfJxJM/dfl+AjmUUuKtH8Knurz\nnJxajhSDuredDMCGaTyoE7jO5bLzybrq1mBwNFCwQ/H/9RafFCmVO3pXUQ2C\nGuBB9eVvVLuPOPcdoy0mRvgYOpbUiMDLGR62pn+X6Lh1cOXw4/1hCAJSvGaB\nh1jZNXAIxHSq/JhzfI8QRsIieielOUBEUJdGq88LFo1pEwGPgv2hNEmFl4ZU\nLkDIFV/bp++0a9qbVHaC0UpB3uIGHBMpYt2xZO69Oz/Jrbumc9fS+YZMu3zO\nOEK9UeW1ESx8SaZCZDVEtxbFebSBU0FwI9tXlkUIEAkKo1HX/Aj6kvx9yKBi\nB3cC\r\n=P54Y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC+gwEO0U/qhr1oWuJlPEiArEjQgGLurX0ujdwnTYaffAiEA+67Lh2AW8fCkc44FnlO1LqzZD+9hyEJGYbqYuU9gCRI="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.4.6_1575728421786_0.48060536864612713"},"_hasShrinkwrap":false},"0.4.9":{"name":"@baransu/graphql_ppx_re","version":"0.4.9","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"0b84fae7ad8987166e2dbd4a11f174bd609d134b","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.4.9","_nodeVersion":"12.14.0","_npmVersion":"6.13.4","dist":{"integrity":"sha512-FQnStD9Pr+MCVkQdpY7+qVaJuhifzCvcYAzL7KlV0zWS6PIvZTY8M1Dllns1adBAuaGL+RBIwXMHnV2UKwCPcw==","shasum":"8cdc034d6c5c9829d296f8bfe636da91dc03b968","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.4.9.tgz","fileCount":99,"unpackedSize":88441205,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeE3WVCRA9TVsSAnZWagAAGawP/3xQvqW5NYN8rrU6BCYi\nBy8oEJgaJROsZimR83rpacLfR1hXv8qvBbZzcNKxUlt4HKEJGj/c3Vrh6I1y\nEV//ooD+A+vjzoKu4L0fJpskj9PLvtPBACMgUSZ3GliAE7DQY7+qhuPXYcBd\nbP6KqXiR/XarHWFlHymwulRI7RU6iTnD5dcSoOXOeAfPKl4eHJPHKPRs6n33\nGvLBrBp1huBAqQvTFIvqdVm2Cib+SrTjYet0Pwvo7J9jzbpqm5/OajeReYh0\n91DLzyy2CRfZHRGi+yQRgzpHrRKM76vHAEb1qnmiQR2m/4IiFRC1Ni/EbsFc\n0Ks4VhS0bDQblYkgBjNTgWdICmM1tvkJhOQ0V9yBhXMhVEfhriizrIcFb4H7\nXgMhbZ2BonmK7tD2agg05LaYQnCA69118rgr8HZiX3K0xX/Qi5gMBjiWFlKd\nZ82QuLRCKnPI9fEKIqbbZMRfNQ13t8HWur/yiwbMryquXspvA0XnHlO6udI7\nZGn2ww54CQ3IJsGky7SswM4j2HC6YnBOVXunY/L8BgdTh7KjcLPk6rUbVFOx\nxNTphRb11HQgg6c88kxelEVtogYjea59Ufe4cq5PwjXYHBKtz+gGLMZo8bzB\nYU8ri6iVw0s1xexZkU6R0TkJzWLuqmeu8nEsBHc6K82+yPS4PenoaPtB/xPB\nkkcJ\r\n=FsPi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGxUeA1XkuexwU9+ntmCGeBJYNypPrrOReTS/Nq4Ajb4AiEAmBrZ5LAU99NARS3KbbxKxTDrRulHRVtwN+IlaqcI8RU="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.4.9_1578333588293_0.6812135209828032"},"_hasShrinkwrap":false},"0.5.0-rc2":{"name":"@baransu/graphql_ppx_re","version":"0.5.0-rc2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"f65e6f4a6d30a5d152418b66e9b4a9e40dd43e4a","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.5.0-rc2","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-UTDBBZxBr6Pma6X63NhDbqtmWduY7TAtkLbOG/HDV/Oa4Jtk37FNb0vieTH1Qqp/Q4vKlzNtx4YTw7PoWTuPQw==","shasum":"969dd141a0e85435a225867470b367161671b411","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.5.0-rc2.tgz","fileCount":98,"unpackedSize":88470800,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeGgQnCRA9TVsSAnZWagAA1V4P/3kktKRzg8sRQCeBzzIa\nEnBOb1FZ0OZYz8Gz9w9MAddSRd3imymXnakVq2OcVc3IwLhwFvtlck6/Eg2Z\nAov9h6eU3LSfnUMtwWdeWpuzid3X7rmHkA5504f6g4xMbh5YNCqSeM7Y1btE\n0PEayNp9PXhSQZI0aF+FKxzW2THib8wR2OeJPB0yI+oCngqhFMdPmTxdxmjo\n7wz9eAe94MzF4gCyHkV2qj9bFghYzJaDbzuf57UNTXNbGEBQhrb5XaOl+fut\n9QaTD8v4++GNRdqUcSqCgqM9YAR0+Nvv9acPf2cwpQNmot7cTFnmii+KNv45\nSXHfEnvqlb7BIAFyhopZA1dkvgKPhMF8MRjr92XLsa+9QdWjE7NFJBUu/Y67\nQCkYm40JI/4X8nFVRwD6ovgUsMxRXsvXW0np/LfnS4N4po3XL/H8Jahz572Z\nZVRTmp32EN9inMIyAtFQcekGcsQqXw60/5QmeBtlPvMmC175VFqoHTyUv4Mv\n5qiYurFAprRMaT5pv0q3ecPu98gcZwkUbtreOEwmqPovZYx8nChdN5P1UEeT\nEjlGVgdBmzqAe1ftOTw+i7DyWsbcwFrb/Se9GOUjW0vPqToWPFD1V/plPO0c\nv3LbM6lzVOGPAaAF47IyaEHbXXm+LZ752QctODmuH+uS7vESRZduIbmr1jI/\n6ahy\r\n=6+aU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDWjigXk8BQVGWYJsXa5ac7znbl58lluAoC/28nFko/rAiApF3qkx55uXOKBCNGUK+K5pCbuaG6YC45OMD5+op9wcQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.5.0-rc2_1578763302053_0.9947880663839022"},"_hasShrinkwrap":false},"0.5.0":{"name":"@baransu/graphql_ppx_re","version":"0.5.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/baransu/graphql_ppx_re.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"1bc90d0cb2cc0cb76ead8d1e9f9c1cb02c199aa6","bugs":{"url":"https://github.com/baransu/graphql_ppx_re/issues"},"homepage":"https://github.com/baransu/graphql_ppx_re#readme","_id":"@baransu/graphql_ppx_re@0.5.0","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-a0iDo4ewC74cqowkxuPcAhUeJ4AQmjKWW0EtnZ2QG/doqsfObOc43bAfGPPQHG2pdtGCY5MwtqbNOVH+5EHkMA==","shasum":"147486c1d1252555e78b89d45f685b48cc293617","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.5.0.tgz","fileCount":98,"unpackedSize":88470796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeGgYICRA9TVsSAnZWagAAySMP/06fiAMkew6U4uP90sjI\naNzHfrg975Zj9fhjMxjZs+E9YayP79GAAz74ASzoAq5oLhy6Oq/u9djZNQzj\nS/BZwmP7dc4yRTABc7ewOZh5LP+CctT3dOCzpgKNaziVFGuyLmsb7ulq2uSG\nWLiV8toLIAC9BsS7Q8VAl1hpY4QOuFBsnB1qrSoPKQT9k7dMnY+AvcsJaBJH\nRy2FRzE8BQiS41Had3m/98dyGo0YtqRv8LHovY0dIBUmNcAJhy6fnuqzb7xR\nzpzzVaGVnDi27x8qakzqzxGjEG5rZPVakOcPW6gQnIeORKJ0+jyVUKxK6uou\ndJBcE/aUhr1gBfBJMltZq0EF53nO2tOK52AT3AdE1nMWFX8MAmLt8i+kFeYO\nKBeGVJz9Ku9QYHYuAdWfrXMe5T/j+YbtKRLMJcBoKnlReISq5GcQdvPL8AtO\nnjyH3pGw3ysYNZ6x6bZesKYtIQTIDZy3hXzecvTE02R+btRoP6X12s3zm5+r\n6xpUtrMP7tBXzjoOAk6RSBNJkhb0zrKqb/TMVgzmi213j7zNhypxMqUWV0n5\nVAqPe/bcgZfcCRyuz9vYnWiq5IuDdVP8Y2bKtHzpPd1BJDZIscHEeAjAGojC\n5B8VHB9E7gg2whMrDQCTLa3PEE/5d6/gzTeIKmaldA8ffbLKOpMILt9fkwiZ\nfzap\r\n=UtOW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCDIFFgCGmYaWxC6R0BEI/u13CEF9USoKSY/a4r3PIT6AIgFg9yB9kgzkVdQZkXyO1dmQ1UuIWCafy3Bgkvlk3Qxis="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.5.0_1578763783194_0.5989558221493829"},"_hasShrinkwrap":false},"0.6.0-rc2":{"name":"@baransu/graphql_ppx_re","version":"0.6.0-rc2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"2fa160d7c98aecd1b59fa01ff1d071730eac1d0d","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@0.6.0-rc2","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-SOqKN1lGmzrTrlGXNf++LuCnTWPH0eKND1anxmnmrfryUldEMNmHmRbG67vpzRmiSSrXq1N4o7ihZNFwjQYyVQ==","shasum":"19b7ee41a33ea6ceed92195241870c8e3faf6379","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.6.0-rc2.tgz","fileCount":98,"unpackedSize":88470373,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKe8uCRA9TVsSAnZWagAA3IsP/2H3kuZINZGK+lXrVyUX\nkke4XFFDkIyL4Ruu+BAWRkLrVQED5IOXbzztuKQdVJ/kTf/ohtLW1f7FBSzX\n94rnwgRkw7pbjgBAPIsoNpOETy+NHVEh4CxuDXjDDepl0fhmGQOQlQHvN3ot\nOvACsB4VsKveiEdEpC6fbI+CA4Sq7u5vq2yRc6kdDjSJjLGYwhK9MDuQ+dh4\nG9Jl8zOqMR9vUTkjdqR/OKw8kLK3fLhuEN3w6qxuEhCbcElnZ9uq6omkZDtk\ndjc+Ks+dxGqfOw8T/M2PGlRBF7sJNI0J6YsfJ7uef7/Oeo5KMHZzVyJIIY9/\nPpwls2JuWCz5irHx8mUeXguU1LqT37Ff/WWWxl3Eh+6B0HsOoLqC4f/BCMdX\nvG5Pk7vwNBHTf6EK0SujUl4ixVzPl0JWOQEEZJaSjKtRJzVFvJaJ4pZP/ezD\nOzKS0MxjKiBhBRd5ix7xt9NpmUwnMblZO96GkamvEyfgdHSjKgMQP154blo3\np2quHgRONloGtTI8C/bcCk3QGrYzRhFCZh0NZG27vvjglvNdKHWUcFn8+yRX\nnuCzvBNBin0rAmGEhDghuVF74HvHNJImNHHm5yuGLw9TtyCkipAhqkizWRf2\nhW2mNzktOccIoNRKun7ZZuYWoYigUiWYQEk/APKRJDFqSNmsEXAGULVEqY0f\n2dd4\r\n=mou0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDesa4q0x8ARsdZM458wToZFw8+62djis0yiDn7dwtljgIgcuYdDHgOuitvgnySWSv4jtAFiRbW9Wxv88S7+w9XzdM="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.6.0-rc2_1579806509486_0.7829543426968122"},"_hasShrinkwrap":false},"0.6.0":{"name":"@baransu/graphql_ppx_re","version":"0.6.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"741398c838690a2d40a8ce5da3272dfdca0ec823","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@0.6.0","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-BHGcDihAyhLD5idRIAJybtGioWicuJHSjTj4iVkl7ZWgMSAmun5ga0ruZIEwJ5YCLHCfR5P8+0EJIYeF8stmRw==","shasum":"3e1738265490d044a26522f3b50e64feb4e2e3e0","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.6.0.tgz","fileCount":98,"unpackedSize":88470369,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKfQuCRA9TVsSAnZWagAAa5YQAKLCAudjBtwf5yYduyhk\nLIpjKQSI4mfylqfrMpONeUu9F4+W6lSUwV0WHD44uOei8eQ5qPO5UlU385af\nl+VVvELSC+ZvB/HGw06OnovrurLvUjmA1gBajxgyxUmCqglCiAZ/BQyL+Oo/\nSjaTCgR+3CYGo8luKuSdtICs3LBQAn0Ftbc8SBnmze1nuHARId7axBmVv2Ee\nbEBf0wFyiIig604NsEfLnJHyU8FOs2yNY9mbw0bZN59y+9ZbL0Lstxg6Koar\n5aCKQOtP3qA1xpnDF4Nn7a7DbnFPrj2Gm+8G+DQwmztoinOuRRLCirPjJojt\n22tl06IdMWRFqx3FwuxL5S7TtxkD4222zcztryjXDWZ6VRiD/AkJ2l2cIvD5\ntRTPfXNwcppYN8cxhmEt0z9K9TNVcc62BX6EPuvbVcVqt9BS8dGvemxZS7wc\nJyhyQKCxnQjX5Sj8iHGyvuf2Q/Mh68SRI3ZiNSu/HidG0aAa6ggEywokszR8\nKYJ6UODguP5rHrxA+J/oUaeHSdr+NXVRf4V6fg2QJXb/zLo1bJFtoccLTxP3\nEW4vqDy3Lwhc00+uynQPrYQPtLHHpl6MTU8ijb6Lb/ZYiNiktfi/2NT5p7Cw\nJqnfczfcyDYBnRzanQCCpU3QNDG3BTP+7oPex3jfQBIDC3BOBtVJDiQHy9t3\nJW0j\r\n=wbi/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkDCG4WC9B7hn+PrEIQy3Zv8vzZiPHQ90oolBFeoJb2QIhAIFlPz23hjOK4nAXltzBQZV1ViQCwbKEMbKp7ca1T4k0"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.6.0_1579807789404_0.5203843482826882"},"_hasShrinkwrap":false},"0.6.1":{"name":"@baransu/graphql_ppx_re","version":"0.6.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"479ab539182c92a36a4620421387b2d5ceea34f2","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@0.6.1","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-jrHTlTMAasNU296RIL5ACa50Dj2YjP/ZmqLph+VM2Nso24B80ujXJF4iOdsiNh5DT48FNOcIVluCKtLrFQw5qw==","shasum":"7a701b5f2f1797095a034b5b6eca2a5d8781975f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.6.1.tgz","fileCount":98,"unpackedSize":88708771,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKiteCRA9TVsSAnZWagAA+zgP/14HpRfn6CTLJLuaum/h\ntX/JJVsrd8UnxyXcXGIdtz4uhq9VNp1I9vu0x2hoOcLkb8qR0hec+nVM9c3R\nZRYK87Agcbo7t9pyAPcK09/po0/sE+yBeL4HOphtpopZIdeD4vrwKFQ/amaH\n24u1HxK3+wcfMaHV0FYRn2N2r2rtRt0MGk71gpYnxG0uldxfx5k7Y3jsf/wi\nw7rf77HvNLZ2d8QMheirhn3Hi5Ty7tqc5HH7Qsv0Qtjh8hqpjL/NIZIRtpih\nJAUKZmS2yEMc04YSrIsn8DNWUjZyloHzMldMjPL3jWFfD9tu0LIsr1ex07QT\nLmvO8nyBW7BGMgt0oPWDYN2BqmEe2F2lxLYs+/qEDnfH/ibXeeg1rDz/zp2Q\nfKSE6a5k7eQ0u6dEv15vEfmvBdh+A2NZ+HLki9T++goinTEJlQ6KCSNLIBun\nHlupnd5EYRXT/tJE/+vrZJPOOjDIliGHZv5cmPHU2HkrLfP8Jv+SC4YzSR5N\nMAtmkbMH3FsDo/QenShSwrjtMlKteD0G6DatumjdBAPvLS1uhufa7WAov+U9\nqQ8+LtmGf9pM5pgtOhY5a4NxqNdx9S1Ug5hbZBH2zvs3QcIzZ5HPJc5nKBFo\nq3IVWM3YgZ097i7612FsorRP+36ypnlNVItwqEaSlxhpk4/X6gKERidjkeaY\ngFXf\r\n=SyBS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBxVIxevODEv3xDELdDCZaY4+JXnaQ8AijmSwBv2nxEbAiA5Gj6HncaBX/VPPrrnmAhgGrCFDvMKuLQTC6L0VTHL8A=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.6.1_1579821917212_0.1356562168748916"},"_hasShrinkwrap":false},"0.6.4":{"name":"@baransu/graphql_ppx_re","version":"0.6.4","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"52539d8189b13cb2766e50c87c5537f60af87b01","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@0.6.4","_nodeVersion":"12.16.0","_npmVersion":"6.13.4","dist":{"integrity":"sha512-YKVaQM++ldkR2ukBCFwxS2e4mnygGAf9QNREkF9gO9ChzJDpCqCXV5TJsFVFccos29R8C7dKctx5xibN+vrUnA==","shasum":"8a71b9e52ab7bba6fc382daa5ab6a203fcfd698b","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.6.4.tgz","fileCount":141,"unpackedSize":94791108,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeTDG0CRA9TVsSAnZWagAAOBQP+wYCp6JscXZv1x/dTgrp\nHBzNyMr2uWuH212w8Y+hLKErpxsGhS7xE8/TsNe6O6fOOJBYb6cHT1KMrLyI\niXedM1ObFWmqQ/t/AhTTbLdTz8V4zf9ogg6TLUpX0bFjtP19D3aHD8RtPsC9\nnMjrDGsicaXaw0HYqmyExSVRqP7RvEjbMx9i60qztbMN4rfRrg/rOF9iL3GJ\nPsQX/6lh5PhdqHAiyjbEayiLD8vjOqmuCyGSNxM5eYq3sc65JsWVbW1/jDS+\nkSFXHEz2qCnGtZ3CtcJuF5ykpOu+lVs3ys9K1qkqr7Y8dq9SfPDrk5C+bBdK\nkOhMKOLoR8PRPZMavk3o2dpKq3PLzn0N5fYMC9o0vmYWEHddnL6YscnXzOTN\nEmpA5j9C/DgNovycFcz6tvO9udjsgdyJaSKIBuTwPsyry9CuY+dNS5h1rAHv\nY5fimUZBhNh7oHYJTGAU08y/0H4HBOeSB04dFTtSo1DzoY0FooDETTSlaXQg\n1/SkqnliHfWvf+OGY8FPFaC2rU6k99N/IXVnPDVr4ADCuMepD62u+0raFJb5\n3HZqUl6Dt2IJKMZuxGPySmMrce0WtqrHVLn0G/y9qmVhx46yL6hAEPmbAPCL\nxqbhl3t6I/du+8i6hxCARR4U1QpteOcnp5NekB6fozL4WrzupiopSUz/gpqf\nO9+p\r\n=2BlS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICVzql/Tng8eWnMpLZoDziDmySuh5WgYY+T7fIIOMoYVAiEA5T0clKRIEYClz388+acS4NQUJRQEeJTmXT6OqbcFAmo="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.6.4_1582051763132_0.8691227051081256"},"_hasShrinkwrap":false},"0.7.1":{"name":"@baransu/graphql_ppx_re","version":"0.7.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"fa8f5a09210d0c4f8cf208f0a750dc40e01f8426","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@0.7.1","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-S9RYUWk8IkFxjE1Xl5eohRgbHJP5nCWOD6J1hMV3hY+D43igDrILq1doAXJatYB82BxcsrBC9V+VeU2LtCxIDw==","shasum":"8146a36a94d56e65692d74488e2bd6cbd4eb8dc9","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-0.7.1.tgz","fileCount":97,"unpackedSize":56058964,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeVBcLCRA9TVsSAnZWagAAjBYP/iiI2hczhElT8T5pbrAt\ngv0LvfftVbps2s4gS39mrEQxxNzFssvq/YU717cCGCYOrGxNlZBTqDMTcWni\nTUIQV5xecbb2Nvx6dOYi0WP7Yk0Io75bIWzmbPm3V1Xto095p4p8k/Y6qXd3\nrVEUXRWB3KtpC25jyFYYq9EKLersc4QG02cCFJrKqgmif6xWgi+wtH2kCznN\nMDLKyXzZajrIc0+GwXURmCWzy/Rz8t1OLgRFwrQav8QqPErUxZVT2FulVOCB\nTmkr5Gcn/OyEW0ZQxeHo8gUd9XhuLmmJF0IME+BXaISOCM6IRrDh9rhTIqyb\nzRX7hB/4INiVb7ZLNgE4BgYIE/PD2CIWI0PyuiFGe8b9vvhZdDRWCYOLVmZN\nRLF/PDkINncf/YXB1qn+ATnQpen0I544YKxTJG2E+ZUpalBG5mi/38hCbcNb\ngi8Pob1zUxZXbrgDv+jLcrVrZUbBRudFFeEJpFOapql2Pcudi/Y8n9xdkeX6\n0c1AbhFVa9C7GRd8kSnzJ4NXLKQ4ZbL+wk1Q5mmIfRR3zWNVVI2oYwTh6w1E\nvLw0PgTy/onNvOl94UtKa0q7rAuW9qLItJR4ELr/XYJ7oFh+qU0OMAGRG4HV\nm5U0jn56GhMAz4hoWsJMZwe0CFz7eUq1QdGgomTU1LREz9Xi1rwkKi/W6Sul\ngf0H\r\n=5r8+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBk/3VET+NMq2385Bn2Gd7dDEc95V6o4TIYLiIHVYnChAiEAiubW4i0lhhh/c/z1eRKWdtiUluats4ZIGcXQDTqNmJ0="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_0.7.1_1582569226009_0.8435654623297935"},"_hasShrinkwrap":false},"1.0.0-beta.1":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.1","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"c0b331af98cc9926fa632132a0409fe3b11668d8","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.t_raw => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => t_raw`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n- `fromJSON` (`Js.Json.t => t_raw`): With this function you can\n  convert a Js.Json.t response to a `t_raw` response. It is a no-op and just\n  casts the type.\n\n### Types\n\n- `t`: the parsed response of the query\n- `t_raw`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`t_raw` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.1","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-4dK8KHhIff5EMgb2uIlPej++xNx7nckMB0DxzOjXs+AKziGxhlaPhKOZBdjkcHWxMMgYq5trG+WW5IcWtHdFKA==","shasum":"584a560ca2bf53e25788b9c2582a2585e728a7fa","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.1.tgz","fileCount":79,"unpackedSize":57886196,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJebyMrCRA9TVsSAnZWagAA5FsP/RwrxmsqOFk6VN7Gp+hO\nJ9FHhc+T8A2n3/Egk6a8N+RDjpDDJ9KX2Tx+dSRo1I2ljZybPkEi1r9RwRSO\nNAex2xKPvbPS7Uy3bxOWn03pj9Feicrn1Nxi/8/un1cfRlhmA61bWi+enIXn\n/MWrJrQGJPVE75bWQpTSxvoewe34OkxmQwf6gZS36LuwWp4KSY1pjHiIIbXv\nzinfFrDxRYF3sKqimb3CSdzHB7TyH9wWy1gYkvcv5wAe8D5c4PemRyxmZ5xe\nyrXQ1s7bpa7qYpsbI6ieEE1wn3dlg5Ry48sBWLEqtGTc7vFowKr8FXpwPtgS\nFNB1BjeR6U5nYJwc7hGa3SZbwSPZ+y+y+5ubcRamNlWrcTyTETsBsKmYr9Tn\nzJF1/6/x1bV5Yvf0GSBVO96CIkvhpSY5Rds/tRo1/40hs2xWJhnMinyEnrjX\n88Vy9K1QpBPqfmA1lNIXQGy7RHKPd5D+OXx2znxIvr1YbgzYevUdjImUVtgQ\n0BaDBo0aoAZkIcEny85Ja57S18ZUCwHTN3kslBPJnVfFDLDOeO9jsB028Vio\nJT+uLTVRS00OSuk8zu8oZFAv2HR2R2JQXBqcef/WA/W73i2WUrAg9k5oY7rz\nBomhaeocLcr0t8V0KBhmbAIfeHw5SKx9smYcJDf63jt9HFM7sMxMmG1JUqWa\n3Hv2\r\n=BoFG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGbgXuGL0DHisj8qxwZ0ykUIlYzV1qQsPTeOIfneKc2wIgTyZ3TVg4GdOdI/f68/afwDoyVavxYzy0RYIR+vvK4M8="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.1_1584341802412_0.6973142347059427"},"_hasShrinkwrap":false},"1.0.0-beta.2":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.2","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"b0fa49a2641b430090ffd6b4d2441cc980c8c92d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.t_raw => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => t_raw`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n- `fromJSON` (`Js.Json.t => t_raw`): With this function you can\n  convert a Js.Json.t response to a `t_raw` response. It is a no-op and just\n  casts the type.\n\n### Types\n\n- `t`: the parsed response of the query\n- `t_raw`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`t_raw` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.2","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-7BOcJ79JCQk8BlmAH4CjxrJjGY0dzn7Bdsy021hrpOLxqnPtsewI4IVud6La7y3KtpFESUHlpqBaD3OAXnz0pA==","shasum":"49c0677a6e278373a936e54303d6a60bbd4ca288","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.2.tgz","fileCount":79,"unpackedSize":57875047,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecdyuCRA9TVsSAnZWagAAK6wP/i+TPu/7Z+pmbK6BT76a\nAozbByrDDViYKO2rE/gdyfubc6t6CV6qfvyjQx+tV1H14LezZVdt0M/y0y9b\nslJ721oDlJx3X2rBpx66w/jdKybhxc7W3aDoAkcsOvNrgHEECanRrcDizGrc\nzFhueZ2sk2/PUL5cI4ZialfGXbDKdX51mcMhk8EYODpfq90SaoMQT/v0CPGB\nlb/sWFbLcgpr3Qs89Z9VNgpT+B3LzjNGa0DrWApWj9YC8Oop7qboKjro/TXq\npbyyF6hNZXbqvJQTrVXnvPgmkbXKsck1R7rma2bfiAsxN/jOktLBGBwZr9c2\nQl3fpDMYsKEzNjTwyU7/TBX6uVfBgmE3ReK2urwhDu+JiR4HA0mes8eGscXk\n0+dkM4Ed9NM9pXwG8e9frM24EcrZ92SjNrQgrdCZb2VyEeMH03XSRMIMYI1z\n2X8vN7Bwgfh5Sa6Eo82YXxEy13TUL7cOwuoancSMafwL/RCyVImjcllqBK0q\noSgYsA7NfJICPQA3IG6hMXyKIOtn82y8hhNUDsTukJirAhFWXsTp4sK2yDHE\nT4mgMQ3Re09kFBr08f+ECN2l3c5ML/s0/+yoLil529M2IT28qw0W5Kp+KRp7\ncopslRBadywozGP7WcgAtyacbpkBlv0iF4X4GvqIbKNDhvUK20GkoKfiauOO\neOBD\r\n=1NzP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLhivo8BH3FVGE70NvQNIK7xN+TiB8kmggVRCrl1IvKgIhAPzhV7BkAdQCfe5dEfIRgqiXne4SwKMj6hquV44Of0Ah"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.2_1584520365592_0.13421044721717323"},"_hasShrinkwrap":false},"1.0.0-beta.3":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.3","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"8a16c863e339653e5844bc7471beb66e77262878","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.t_raw => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => t_raw`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n- `fromJSON` (`Js.Json.t => t_raw`): With this function you can\n  convert a Js.Json.t response to a `t_raw` response. It is a no-op and just\n  casts the type.\n\n### Types\n\n- `t`: the parsed response of the query\n- `t_raw`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`t_raw` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.3","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-62dX8NFgO9x21I05QKQTOO6teyA2thwSuLM4RNWb5YUAlFHDSpqUhXQfp2MM4cjJH7zy5qKCzJFXcQT46dsPQA==","shasum":"462249c859000776fcae2a8043e6847492071517","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.3.tgz","fileCount":134,"unpackedSize":58147241,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJefy39CRA9TVsSAnZWagAAkG0QAJcHnm8XLCCuJRQnZYk8\nXVOs6QtbusuOn14yEUXOBURU0yt4PBtPy+n9oX4GRXxgWaLLWGkKZ5TYIoeH\nzwCy+LeIUJQ7QnnmnWmnH8a0BzJaYFbCqNk/FPtVVcdDIRCkUxKFrUoUyjBg\nVCXyiurSCzjlEllG2VN03X4unLkK6r6gVkhUXAyHG/U2sX4WDUapGwWdyUmz\nRyeOnrm9Axu5WlUBGfOpb2KPB6RLNXlvhmR4SJIGsSAr2Gf44grHuV/pOKV6\nk5HKrzdz+tgwO3aBO5CH54YXS49oKtdCY9ZroZE8pb7UWQ3dU8+/Taf4yTVF\n8i9ORWJkMJAUiAFPZztFGtQJGl93kztjgPg2WlpYrWe8VkNsKBPCy47DK3wW\n5d70Zes8u7SJbZMHSp3N8PS7AfdttNqFsRxdVuEPO/BYkh8eTa52Rn5xercb\n6zHBf/OwjWllwF99LpZdyr13H9nQiX6Qgqiw2KpN45VgtWxiQCWvwsvJtWdQ\nuk4UdRmQyGtI/h0LR+OCEiAj6qGyTo/TqXZfDvmFQ2J5bIeZIBRxQnF12bj5\n2USZi5wZaJ4jOoVu+c4R7BoOAOM5W83tUkEEiskT5v6yitGZ2+wwwDQKY9jI\nUhm8LyYOyxdhn6elsk5ZANsKpjUT4wqTq7q6VXfJuYGFH4YrkPn9g2h494nz\ncT+m\r\n=MIou\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICWYpkcaE8Y6qAINzpat/fGdG6tSfmVoOK5OcoOqtLjrAiAihdsG4zanhxwAPvtFcekLP2N6NxUaFN01q8w7GpHLGQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.3_1585393148991_0.008163476798589198"},"_hasShrinkwrap":false},"1.0.0-beta.4":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.4","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"2f28fc13b44ab8a8f67355f5e97035c24d1166a7","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.t_raw => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => t_raw`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n- `fromJSON` (`Js.Json.t => t_raw`): With this function you can\n  convert a Js.Json.t response to a `t_raw` response. It is a no-op and just\n  casts the type.\n\n### Types\n\n- `t`: the parsed response of the query\n- `t_raw`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`t_raw` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.4","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-en5v0ZnVuj8dXPAN1IKL9rdLAa7IXs4LJ2jpJ2VYH+yV08HhHux2up3fikTQr4W6PX7lCFAF7N+Rdbf8ODs4Hg==","shasum":"06e65fe64c3d5e41c9256d01bfe6eb18a81b6286","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.4.tgz","fileCount":134,"unpackedSize":58149534,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJef3CKCRA9TVsSAnZWagAAb/IQAI4IAwEhdZ332gvhfLPD\niPgPDwuVd7oov0ZpUOQlJ0eQmQ04IhJ4r3HviqwYB/mgugXiVEbTVE8PcqSU\nC2pG7NSKIuZasHtHu5FWHnurYLiFUEQSHV1IAHePfHU+bru25yT1y0YeS1bi\n8ZJD7Uql+gCRkOWiXkV0VUaITGJ1PQ3bOq56RJ0OlEgY7vOtld/xMfPoQ6a0\nMI1MWBN1mYnsZofxvWUAy0Hfz3iI36Rmdql3fJ8hD2W7NTUCFPPE5zYMkBSR\np3B/cYNMFcigfDP68e0+jUYT+2K67/TCfcjD4fvFo17FzZUiiRwOb7rbpm/p\nj7v9O+Bxu9bRDy5769KfvjYLnolFGW0jyfankekgohyOC515J5ANmcUUHZyc\n/3C/Z9JXvp3DLpryTqWY2zUc8JrCCFYrjc4+wHM1QrOr6/1IN1V9fa6I53OK\nBhUTvKqecyakack3U/oHpX24x7/twha7Z/22gQoOWRZXtuNVOVixKvZ2jych\nIrrsPtFZ5v9SUFGoNvLphtt1eHs22oaaoxdZUW7uE6U20G2HDipusd5WgA7d\nXFoKdo8AnmlTwxxFD55Ly2L5hB6YOnr7/wAVd/J8vp72h6bjjHIKZq4g21Zu\nf/49PzbNaE3s9W097vm2tmedgLgztbMe948VpXoIkn1ImLrYptSDIlP6j7QC\nZdk3\r\n=kvpa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC5cbm/yyMAYPBjtUwsCzIwZ5TznfPw+VVPSwxxMzZI0wIhAL4eERa53MkMP2rcZ/TCxgb9Kfe51XLUEebjQVSb0Zq8"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.4_1585410185612_0.9591464732351911"},"_hasShrinkwrap":false},"1.0.0-beta.5":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.5","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"30e1b02be9d7bb65244be5e76123152612e83d80","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.t_raw => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => t_raw`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n- `fromJSON` (`Js.Json.t => t_raw`): With this function you can\n  convert a Js.Json.t response to a `t_raw` response. It is a no-op and just\n  casts the type.\n\n### Types\n\n- `t`: the parsed response of the query\n- `t_raw`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`t_raw` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.5","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-9CmJhwoJSdcgZF32MelEoNITjBIssaCwh4X7CLfpIkdvyJC77H5ylml63U8uqlpxFr5zC24nTk9CowXNQBvlmg==","shasum":"843b8f3fd48c7130baed126e5160b3021a46bf0d","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.5.tgz","fileCount":134,"unpackedSize":58149924,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJef3q3CRA9TVsSAnZWagAAG/UP/iMwTHkcy+ZeraaHzw87\nBCvtTIzfZhdWXlmhX46RYfoXdksaY+1IG7Ji+TVd8X5sX14aKsiB/7nahQ8r\nxOGt8QYYHEJgQF4plu0i2GUQoiypq7lRXn2ykL9ZFGSQiJaTRCTPxeXx96h+\nHLJQwDopUPnCrY8CwNjCJBZRxil6JJ/KJXsiyR3wJjjmnVXGpj9ux8mqTprv\nWGd55ZrJW4rIwA3rZ6yF/XpZPMEIQQfOxhnGpPu7Y7kpHvGF3YRcNCFyDAWY\nxgtl8sUB5I7BJU3RxyPnPEojrnuwjJ8Nr5qVkTwau7wjlWSoQsBanCUdWS1t\n65MtvYg10TLpgJJMPPwyaurdTlE9UZiTtbpKkmZmAzF439W3SYE9W4nxGQ4x\n6IiW7ho8aVqNifCHc/IvnWyliSaO+nAplSaDQU4k+dlpR3R9Iqh/wNu0tsDR\nAg+nQb2w+svKowiC9lPir8cngpc7u9T5qxtjRcCGPiBiNmDUPmXuHGtvFhes\n99mZF6gsiy4wvF/MtHZJdmFBNerszm4rVZ/qo6ngggR191hSdW55AuABlYyX\nQXjb/HXR+nEF38JHtij+kD0QCZgWJVdk0uWnJjD1KapQD0pKaKtCTI1EhZci\nXvQAfnd2nf2zvO2k9dcXKwiIuogS+5d5Vv7q00gi4amfsxjkDNABowtoJLQK\nVpQW\r\n=B8V+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICD+MX3XEsTlYRPkmJB80nSq29FTbG5lnIs/tCwE1OVjAiEA/03ijinVVVGhF+HcShkvHUH+p5rcFmVU7aCazbKDZu8="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.5_1585412790843_0.6251666418564548"},"_hasShrinkwrap":false},"1.0.0-beta.6":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.6","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"95db86cc82be0798f26a6d642f6af782b3a1b9de","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.6","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-kGg0+d0QSk1GO4b4rk2zR6b6Hc9rPmOuE+NLb9zouathHXNNm8IQVMRo+wBTHSNt1Yg51jlXlTSc8ZnBiKgnfQ==","shasum":"b93f67bdf81f3a41f3d871b3e0e5d59635ae068f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.6.tgz","fileCount":165,"unpackedSize":58395473,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelDZ0CRA9TVsSAnZWagAAZvwP/i7SqlSVrnCzNiJiIWhR\n/mrE2MgyMatB51cfwkl4BljIH5OzLfA3Hb1Kd+NFRN8d7Avm/PDzoltWisgy\nNGnqMlMPw9T6MKoaBwOmlhCYih1WLU2vL6AXk/4e4DwlVaQwDMCxtnlRxX+7\nmE6t8vYOa/yYAnUfJA3GbTOhUvoyiLNwttIOI9BTsgi45mvDT592IawaStk7\nPR+tPKjUU0PNxa3fkERwwTLk7ihc3Dc9R2RYpFkmCv3ka5X3fCPjF1W0Fdiz\nzQvSnHJ/b7FOILhWfyCfiuOibcQ0bBLPz/2YRekZ3UBpp9A42hDQC2TLpmEd\noDqorQway5uboNwYtSjvbHSthx1qZcA6c4dhA+F/svr1m4tCnjey2WgN0zW3\n0+DfIeF3B0AiBu+T2dtl0jWWvbJz/wu4UgFBmN5uwGlzJ/WxjbJOqbXlV0Xg\nLR6yoCvZaBoNpchhyPdcEIu9jJo4vnb9vZOdkm7cpZsqDZh+i6wQzYrTDcLU\n9zuOvJlIR0/vK4S4q9J9SFmokwSqlThu5iYf8/prvKlLYMIgGhvx3oH4+5L1\nQrG+pD/tz+TVBDJCQO2Xt2LQDS3Cdescj6H6MZUiJkjw1Z5Ot3+Kq3bamkVT\npqJSCARCAmoXVNhyiaMwC5a/RBCBIPMIJYsj9FndGgcuhHgNw/jpBIGKg91M\n6LIF\r\n=Kkca\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHMREp6UT/dYwB+ftu9YEy+tERXj3rb45ieSTYLFhLR9AiEAxRwQiI56JRNAB3WVrUH5IRHVY6wv+zKuOkTHlcqVpxo="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.6_1586771571110_0.5885225660649036"},"_hasShrinkwrap":false},"1.0.0-9c572d7.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-9c572d7.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"9c572d78dde323935e40628ce8e2500a7d1f8b7a","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-9c572d7.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-114CuKwuSQNV1Bu1WMnROb5wJUbJRI8ez8AuYJuX7wMbMlZVXZNzHk8SMvQp8dnIv5LGI3FMMQIWDlXJSKwDwA==","shasum":"f59dbb64dbbfdeb2ebd73ab6cb1a4798780464ec","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-9c572d7.0.tgz","fileCount":168,"unpackedSize":58700202,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelrNDCRA9TVsSAnZWagAA0EkP/jq1zTUdkHtSxOF4iJ7x\nLMvq5xxOZib/LxbHLTnsvp04faqjNy5w1/VbZhAu4Vbwj4hGgVwXzuNvybJ5\nyVYVArP4bsmYPdaFILDuLqeYstmuH+nEtj59Np5MZoig/k1begyBbnuEd6QE\npnI9KqMkkAZAx5LAjWOtgdsrFIogTyMFzpqoCkFS3gOMmX9WyNSb3hDsghJd\nB6CBE89Eqrte+pEx9mlTWc4ILepC8B2/J6Qi3mZq0e5w3UNmamq6shP8XeTS\npk87K2k07PWXYAVD+MbOa2KiKh9ZxLhCvRpjx8TowDASvPd+2qhgI4Qw+NNN\ny7z48u0Y1mhh4DzxnpewbRRvMWni6nf/m9fY+vGYiL4XSfSMfuI3ewY7930r\nUOeBRiYUKVQ/97IdX9yGnVEgQRQgzx/WtSa1sTVB6Km37wlOudf9RQKAXltq\nXvGN/xiytp6uGaB2SLWDjUq6OhzkLtGwfsZkid0MS+XqJ+i5MsXOIvd4Txir\njTHhfmvuWZDHHjQC1QqLa/AKg9Y4KtgeW2LpeJ1rHwk3YoVnxrjrbW+s1FZX\n6nefSI6nt246U8wpwvMNS42lFdE24pN4U6rQZ875ued7JRGqRw+RuYfNTiVb\ntdQrpJ3udxJTDN3TJYXnTONbpGap0kJgA3UY6b/0cyVJHU8E6FBnToHfZpAf\n4tYS\r\n=pTm+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDR301Hqittk0Mt7JNqvvHeMCAci2/hgbtNPJCuJPv2WQIgXZaPnZsLOw53QowFkaWP+APPyu5G1nv7/ieI5QoDJ5c="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-9c572d7.0_1586934594877_0.06445961667491185"},"_hasShrinkwrap":false},"1.0.0-7ba26b4.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-7ba26b4.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"7ba26b44cc3b510da83235d6d5183799a9438111","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-7ba26b4.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-OtStvS6kPrN2KIoLqB+kjRqH8YBLjA0hxekqGhQeOHG2e0zD0LwngcS1YNi9zvRUfpgVCv1wV+sOQsLhFBC7/g==","shasum":"8fd1f6ba89b78ef42ede6abe13152894894809a3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-7ba26b4.0.tgz","fileCount":169,"unpackedSize":58699271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelujGCRA9TVsSAnZWagAA/agQAJU1NNB5925BpiB2QQKf\nc+4eKAXrvMrkrxGCJcERDaHwngLBgnFdl2jnXEGveG8uOXGTbrowvVqZ2z1d\npEa/NtOZT2O8Ue+5xWfBc4JeE9zdqc0S+9uYygMTHI6LmhlRAKLviPr651fL\nLDzn8jMLnCclxRRmC6RNHDa5h4ObjCtAvtSO1U4cx9uG7Wp1enBvxCbCkFrs\nvAvRex9z4VkjpfyoGUzmXqXHAfducV+P5RwXBAGanIWm2X60LypZMQxdbPn7\nswprWaFQ7DLeOOMG59CIhnOCIS1jRtL48gFPFiO9gI7D2dXWfqspGlcJgr5y\n6WZcwyqHyprLps/4jkyNvVFa/7vwyAQsFH6FFPzFgTCvK3DLsFoSX0OrP/g0\niU5p0rb2C1/KYoqyKleSaJcjPZQFZ6vaqm+Aw0QOYqXxFRiM0DMNKnbeL+Yd\nirH3L/IaZG3Z1KrJttdXbYVbO00uEyUkbgFrtJOrXeYNf3xGfu/b77ER+0IU\n+ZIMcHL8nqRoXaM8e7odNRNs0Ba/lJSMMoBqKIfM6Gyx8GVDcn5NuWdLO8l+\nVhEeI3AZYXyuuS02P5BLZ3u+LVBcWnAv0wfAqsgkofbJ3szcbW9W+GrRxT/N\nB3HBYLg1GO/wZpVju9BVKV3IV8Wue+kh+knVb8d00E6UxwnOlToW/MuMdZbM\ngN18\r\n=8BU7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC0lEp+1KBJuyXzt5oTS1i/mCA6dqgOQqrU9VU5ab5hDAiEAt/rGF2wzu2CEseSxgQJf0IRJxl+I0RbtaieUkyniYZw="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-7ba26b4.0_1586948293366_0.39661387722894204"},"_hasShrinkwrap":false},"1.0.0-3175c1b.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-3175c1b.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"3175c1beb38d0b69137a1496f98d6ca298343472","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-3175c1b.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-KAXcLPkNiwOeGMn1i43UBM9c48qd4rVJMmlgOT+tPQ3mjHMnkCX3EwVFa30Jnd4bFd3F7ve/O8RjKap5aLX4Lg==","shasum":"531d08bbbf9d4a91ff2c06acf2cd64d6e7c7fc8a","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-3175c1b.0.tgz","fileCount":169,"unpackedSize":58699271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeluk7CRA9TVsSAnZWagAAXuEP/RSWRRn68xEPRe2kBM5B\nCyI0iyuVJI8BK663W2zhSUX2IUtukFOA6tPaHJNFHXX8DEnnNOqS7u+Wi5cp\n3Y6WXw4PyeHDGwDAG3/CTo5L/cjinCsnbaHjfCbdLHxLoEkKLQkCUFs7jeg7\nAlaKZsRkDmfGVp5v0Adlui6fSHTcgBrvxrBZXHchZDszY8UVLBgBXFsGp5vE\nf54zYhTcBi8iFz5v9nbaIz0HJ8kLGu9p0GigqMLNMFnJdq745Ku58knnwaKz\nFShhaM5ZjM8m6PaYmvHxjU64KQMl8//I3Qc5YQavpl5GMBBFuxDGDewliXv9\nlGP+MrYAYnoGbW4+ftc0RpCVaU8UdJcYjIf0CMBhfKZBNewA1wB4QEA3U9xs\n5kpaADlbosfQdvymkv8hrWPLMe2cyD9kXhdtqqnhTa7tBRfWBC+2UPRg401H\nlF6qDQ85uhwzSWysbGX+SiqcjWJmdYZPKjy/S2pRjJ8GYwDJAHIulagQGxDY\nWw7LxkKjytcWq4pqOaxFuVaGsmYrm4ctXbXIn2XlFTGi4McMIjxzt6XOVdjL\nVMRn77ABzt4FlMgj+EJ5KDqLqxRgSHbAxCAEL560n34oMrqyxQyaxVFGdgbG\n6no8cDHTGzcvBsgdEXk1ROtD4tXdIrHQFHZc10zZqhjGCDNJUJI1R8K408Q3\nJ1Y8\r\n=7Zgf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAnNwFeUKRJQMTBoGbzhkCeqQAlsbii1wFWqkyu2ZyOAAiEAwNwJzS9EJYQAIEolpN4VNT+XWvuJbwxr3UYVL6KCJ3g="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-3175c1b.0_1586948410462_0.8187523363573894"},"_hasShrinkwrap":false},"1.0.0-a05c5ee.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-a05c5ee.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"a05c5eed64451395a797e13f288e0c5dddb50b74","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-a05c5ee.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-4KJaDm5QLVkkuM9+/9WgwMvNSWTrlyVyDZdJrNIix+ilwrWO4kl0mLg5II4qmesSJYuZ56kNq3ogZ1AIaP3oPA==","shasum":"1eb851e9f2c3e850f2e1d367fe6f909a911642c8","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-a05c5ee.0.tgz","fileCount":169,"unpackedSize":58699301,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeluqOCRA9TVsSAnZWagAAmnkP/RxrVc7g1c72cOfrEXvA\nh97ZXe+FClRmT99uA2UVXdc7x8KpKbZRw+C28MGrdj6pmZGUTM1Kiqtcjhor\nSVcUSA8UHHc6Cy6UyQqM0aEvAJ3NHW6lH6AWRole7et/N5SLtUP8MMNt/R3X\nJn2hAAarhOb3w5lSDt5FYUOVmpWjug1EW5Esg3llx0IvOIhEMwCgBBwghZFD\nEdn04psrjFeu5U4rixZ9K2AXj13J0tsxunLVgGLHy8/Xf4PQrTEMluWSwdTy\ndGnyPOiLZZ4EsVP4QaYaqeRduomAi68obPO9YLaYQb8yuiPwDAbbAszPA3cA\np0MC/f8PIym3wJl62dqWlScbVPXCrhDft19yP9qGEHSfRxq20vwfMhH7/sb5\nHD/hQYf/qpyBbG23Fov98seo3kCGnZQozJ6sFhVy4plaIbWKn7JnA9Vo20Xf\nrEhcP+/uC0a+AhG4dC/8N9yyjwul10n/6GDsh9uxQaOQ2KV+ZSCs8PFQB9RM\n82rjaFj2ABNM2GQCKn3zxzE/1NMiuj7CyfyuKWLubro21d6qU07EgNtx1NZ5\n2y74lzkcOWtu2XcHSfJfzQdB6Q8F23/adEeSpfqJv2M44qFSFQsF/NY8742r\nWA7eOA8wAnAMMU5wOBNoG4rCC6cYtTp4x1LxoqUntlqmTIKk6PXX4yO9tHMJ\nFTRR\r\n=nntC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDV4OUHBQ/plq7h6eL72VRxbbpclMuGxW9m+egig0XI4AIgGVWXTWKzwOstgvttMgXaDmIFNR0xICrNWpFZV+ei+Hw="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-a05c5ee.0_1586948749875_0.058604096440398656"},"_hasShrinkwrap":false},"1.0.0-1b6c355.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-1b6c355.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"1b6c355f2775e73f450438d70de9bf6aeb9aa7bc","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-1b6c355.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-NkHwGLgcRFbFrgvXgdKzCTRFEG9BZMY242CWcdfQiEP95m1jREIa8SJlEM49EqtTWuJKfSdzHQ9ObNd91Ib+kA==","shasum":"d126eaf17732a93f851293e1a7cf1449022bb525","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-1b6c355.0.tgz","fileCount":198,"unpackedSize":59146779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemwmTCRA9TVsSAnZWagAAbGUP/3Ch7D4n/T/01H2W5366\nZnJAiTUjL016AikNJIKM0NKeJdsBs2A4BZyFmVoL4YYgnsFIB3S/nDDH5h6s\nmnKdafjPo050K4Ko3sjZaZyEIT8a/EjdnN/SbAlsbiQMc58ZF3hLMl3WqTMg\nVKF5z7lr085aKY82nanBASDIueZexW6ZzoJiv49vmqnc/Rz098C5kiTiIAeo\nBuLTIFIvuaxZAuGi7mkGLkBKsTamYSzukFzDL4RbbFhpxbsyu0CovLRx6en3\nFUG0drEDMmycv1u2F2s5jvC6BeA0otKL8jEGKcxpAkJNeVwOSimuTf7RxRwr\ne+ifyOV2sJeTWzXV7MooMOnh2cMcW2+7r5Rqa7l6g6a6pcRsYTF7lQZ4A7Ku\n0MHsBlgz29LEibR/2Zbz4KZwhpxlgC87dg/kTa8vS00ZPSKSBpPMt6NiRVXs\nmXNonGwotuc1Ty8z3Y51zrN0zxN8G0SR5U98BD4SHfCLKsEYsZl/lfqs0Naj\nN/mSqRXc6onmFghr3ClKVLgT1zpMdPZTTBzQ138XbnduQb8v2wY5brII8qYz\nKWd+QbijFaeF1duIY1N2rkT8e3setwI/iaycbeYipE7Lsy9W92+SFC+xcpKy\nJW4b1dzyG4P0LFT+OAKbTHVJi64ee3P82nf9DKYLX+cMXdan8ipOCV//fcAs\nRYtp\r\n=tuZf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDnVWyN3h3FuGTrJPWUlFac9NaOtTL4uM6Dtz2m8KT9/QIgG/lcXEU2DyOzXPzDblUBcQ7bJeGGA+D7BJ5xfwB5Als="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-1b6c355.0_1587218834305_0.42548611528683145"},"_hasShrinkwrap":false},"1.0.0-c9eb185.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-c9eb185.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"c9eb185aa03c7c2d5e28bd7188bd9c7ec7474671","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-c9eb185.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-JozBVBYQCa5AycGJ5UpDDV1xW3Nmnyk4lB5Qq+z9jgKXxb/riRxKfTJoUcGHA4faURhP9cdpYHDf1nypE/MWwA==","shasum":"0fcf5d3b93972ba3e9bb1eae45431379ebbd3b12","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-c9eb185.0.tgz","fileCount":198,"unpackedSize":59146779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemw8cCRA9TVsSAnZWagAA0hEP/34+jZN95TPUKQkfwp9w\n7ixG6IknMf1iY4ewpNX1lqK1+3d0lHUnjUZBnh6+EUzn5rWSmXtykxy87M7p\n1lX/IeQNfqyn2S7SvbsM73QIayB9W7FUMP/HBXkuXFiJTSJ4jKp15IGlOJ/4\nIapJX02dyBlZjtho7MlEKutq+JVEXVpqeCiBPwXxLXsDjvv+Ne5TM4kzQu7v\nVAPWBXDDFt6ce+KZKYFJWIlHj9SAO8FMQeD2jwgbaeii9mM/qlQvsINZOTbo\nLhUbziTCzhIWIJqAPj7tvoOfk2rwl+56hM6iiOsgXgZ0reaWFa6yDSVnYX93\nb8nt0VqEYvtoV55K49GTDmglBvU/ZW23YWIKObzxcev2MGVokE9o52nG6ocq\noh8weSusLh7CAy798wcDOCU59B+SG6JWHvTUULkb8Gb9FDn1GzSz45QIdKI2\nQhHLm2i5bOHZSDu6GvMsoLUBFD14IZ1Mp/zZCSq/Xw91X7Tl4aqXegGM2q/P\noo0kXU2P6+2SUf7bPgeLvLauR1UBljNnJexZvtAKXQ1/d608xDX5w+ZXrx/w\nonpIWSGxel5RxFOVn+z1M6MIAwepXu04BEqGbpXIE4uELPUS2oCZNXdtVONH\nAYbm1py3yLndrSnfySwT5wzPegXCBv1g093ZGudR7xC2QRnc39PU9QFk3AhZ\nFGs5\r\n=7yms\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLXzjeCUKzs4NRfzOCcpIIBv/GzUBeIpTQl9yHFmlqFwIgE5rr/qwFIw4mNXOtIVWpF4FZp7OH9FZaNgTcYs+5NdA="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-c9eb185.0_1587220251463_0.7474147462396306"},"_hasShrinkwrap":false},"1.0.0-beta.7":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.7","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"gitHead":"29c8283f435439561b7614fe905ee2ebb2def272","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.7","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-xI35+majESiCTWe/9/o5otgqp7T44a6//zaVupuxj7W32VtBeQskcw2omCJ5TGnYWQ6UB2QJFTRhaa9wgeuqtw==","shasum":"7dda28807092d9c9a1694d9331b03920af121e8d","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.7.tgz","fileCount":169,"unpackedSize":58447173,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeouvCCRA9TVsSAnZWagAApnoQAJUhhbrzl8waKVnymrKq\n5ktM6KBhlzy/nSUDysGes/u8ExXExp83feV1sD9VfoI+RyjBJwsHHmGFZx97\nbeGISoxa0dFtLgLq8dZeYuC1YLjKVtvciz0gXpXE8JZqZxSxudDlZb7vm4dv\n2vwh881+y5e3P3LnZfWm7wIQPajR9r9DwRc0rnaQ19TZKYdZZYEKkO9n+nNo\nXiP8qd2Mx9tRsmUKOYdZ/qI4SrNv+Nam7gJ0B6p2EQD2sutpKV19WMC3nf5F\ncKEZH8BAYrd4BeZI9AuUXbs9lY/vMxO1mg5vxkmlEhayL5z3t1OU5vWItpza\nKxLeWhA0ixfrLIu2M6tSAjPWYg/N1F2zitr7KfgtMzoaSm4tytvrzhSQTcR5\nBxZj8SCDX+iaOV8+NE87TEIkzrMSeo99RLpjP39BuXVI4xKHjdOvV9v8k2zj\nrzdUKTcofUyo/I8GwrW1J9WfRmOMk6HWD7aY3Lw5zV+PoavpX6DWkWBQOize\nlSuR+OS5qWsFEiviy2G26IQ0q7H/6x+o/JoaKMWOIF6Js9opvcaeza6LeuVT\nd++IMIPOJMFRD8t/wqAWPRW5wlcR+uT0fy+7LCW5rvA639hg/Arn5jwxIoJQ\nghydKnIWwnxaU7av1CVHyBRI4YWSNbshacocoHSj8OqIlQHhKNp8VO5Cfn1b\nafBl\r\n=tX6G\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFRpE523QTRvH0OL/tMdXxPFyhpeOtRiIhM5AaisiN0aAiEAzbDAffI0yidSW2IYjJ46EsAKyhhfgbf0iZuJ3Rvphrg="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.7_1587735489535_0.3638330594990655"},"_hasShrinkwrap":false},"1.0.0-9b6a27e.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-9b6a27e.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"9b6a27e92f1cead17a004949f7c6d6dc88d1b9e2","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-9b6a27e.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-UH6rpqc+CHXUso7DraRS0BDomTvARNhtMVlSkOoVcodOJt09llomCCGWoTiYEmrqTz36GGOzPbN3Sh5X62E9tQ==","shasum":"8bb2638fa791f0e7d04cefb1613c463b7ee1907b","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-9b6a27e.0.tgz","fileCount":197,"unpackedSize":59113142,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeoxGjCRA9TVsSAnZWagAA4OkQAKHxgwZPnTxgTyljhZbZ\n6++eyzX/bnytXz12rdVvuymcmU4F1pQ0bztIPWUPQS7jmaZRPEDaNI1YG/KJ\ngjtHPSNOw2YbPLu10+yyh7zerGLUQ1Rwaow3SKYACoNiEpFDj6XLRyH6fXsE\n5B0H6v2cZ+FiLNubBz3m+skssoJ7hLXYVUiHK+qrwcj9MxLVrw4ahXE5Seu6\nvAJLql+M163MldH6Yb5kSUn1X/QkTqIdCWfe3bskpaETfX2Azt2iIorMN+Ub\nV/QqsbjC2Y9AkQONkeJabFIVwydnGldW53rAYRbTeTln/FsetRZi2/Tynsrf\npcnxrNLM8JEw6LOAhmWjFhLz2kZULB7k5xxrHr0ScFfkmFXetMJF+iQ8ecl3\n/KrZVh0QjUYx98XMuTIeQe2oNcZU+521P1j/RPngvTtAnuoCV6QNJsOyimdc\n4BgN6yvQd2V9qHYMppJ6p8q/FWEGMucMtcN3J+5X2pmKQ6KK1vlMqlchc0sW\nuAApE/JiVL12SyYNOgfnnW0iZtVBBhGTis2/JhWoDKzcEAENV3gnhJYIxNqr\n3olB/p3aYzjmYB+XoebGWNmL1yTGogP2JqD4CDsZKRgItYKmZZJDxyvQZQEM\nN9fXKofGZxQ3Y4fckhfvZvh5zDwljYL6AZfj6YIJoVLbkxvoBDf8IvcrjMwl\nbRFK\r\n=l9mz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDEMx4SdY7lW2Cw+6QMNxHXlq2B+woeKyfrlM9RvBT/VAIhALoZBve0anL0ITfS8z45y1EEfKmESt8aZDplrThXxia4"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-9b6a27e.0_1587745186173_0.2611700301401847"},"_hasShrinkwrap":false},"1.0.0-a6ca69c.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-a6ca69c.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"a6ca69c994ff3f76d1528cd77b8f2658e452010e","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-a6ca69c.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-xwT54G6PsTYB/gb84EenIgSZETEC9ImZgDV+99YG2dVLeAZ6408xGrU0bnfwW84kzprZDkwd+Ur+rVD+Y7mtdQ==","shasum":"e080a123a9ce76a872331e413d8ef65909704796","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-a6ca69c.0.tgz","fileCount":197,"unpackedSize":59113142,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeoxH8CRA9TVsSAnZWagAAiJ0P/2diSAhiLroBkuqkc2Wx\nZVaqc7fC41tQ+0BrvES7p+zzm3tVBZzIqw84BZVi5TPNVDpLmHjLr+jr89am\nGSAWs5iqXh5WgJTiK0e0NjQWE0m85RGrK9Eq+LlT/44y4gwo6siQwM4+t9Gz\n82MkwtGqe0ywxuy+CRTQm6cTkIa8Ca9krV9a5wbuSpF9JxfYrpcHmz5hUTzV\neaHkv2fWcfzER4Nh+mwEMrakFH7Unt+uMxTSEEphlNxw1uSG67VXEe05gLWb\ncZzOK3cz9EeY4/EMEyJQp2N+FUShj0MPcTBnyYK18SB2NwagQjX7v1LSAN4k\n2wWCDnqrELwGEn91fVbFZeOPD+m07/lUCidSOAt6wyy4w6xcOlt4g/GKv1+Z\naQtiLg/7tUXox2h6PQbkNtrWQd2InI8VT6QxBWHi0Rn+3QmAh4BFaBcCEeUQ\nw4YJ+8pCaqsm5ePyXsgjl4z8mzUBPoUkhJ21A7P4JDpfO8L28Ae5XTmtJ8VN\nLVqDxh6jCkK0eEA1kL7fFRQGppyJGZRmvfxSRNYRCIO/vjUY5+4w/OkUnLS1\nGq1owGJeysBDst5for7BJSweQANzs+StgxchBB/yjPm6IkpzW3G7dib+9+SW\n0hc/1jTc2ha0i7vpe8a1J8NqsXL+FqoxAwd0pMYNZA7AfosNpE/23W5dOUex\nd1hA\r\n=Tnr2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTBhipULj3pQRhEGzU2BiMayuQh9Nl2e2xz0EXLBpkVAIhAMW/Zgl5FqnCfhL4CdSELV7+JzodQrgaDouaRcVF09Ah"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-a6ca69c.0_1587745275244_0.14634615093019487"},"_hasShrinkwrap":false},"1.0.0-29c4356.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-29c4356.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"29c4356ee7ae51d3ad8c8d7aa9d9b9e98d504fdc","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-29c4356.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-kXBriLBk1abgsvBUmgsrO+Hoogqzbh9Nx/eP8aZTpgNPo0D31+U+LrdBPf00tHib21OHXzwR2HX538Vl+9XYxA==","shasum":"f33263189fde5e0c2003d110564462a882784ae1","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-29c4356.0.tgz","fileCount":197,"unpackedSize":59121991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo7cQCRA9TVsSAnZWagAArKQP/AlhFPN03VNUqDkOTDzW\n5SfziyNWt/HWI8xvkj4lxfNSHWGy0mmFD3k21C2YD7s/EVXYJYUJ4GvZCXRm\npRIquWpJsT2FhPkgwSRUTalDd2iFVM9lEH8PhsY4+kBQFNKVqb/OJJ6BobOy\nrsX6R6o/3rwySnib/7OA3gJRX7eP7XPlT3cPzbYFFabc0fLpHd3m5gq1k8cq\nrRyeTm7PmXTgiJVKWfMy3Bwcc1IqKt6XdDh9M5Z2VHyKW43PulcVrQWddXf0\nf7UO7CxhM4Qm1mfiK90uRiQFHoI9IDqdtNaXDwKPtNXPyA4mVQYtKQ1DYF6/\nS7sS6hZ8d72GG4JnWwm5c8FzXnHY9zkitJZvbUWC6PSxBVOfdRghuQlgdvoO\na9noYSd1fHJ0MGWQviw9eNS8EW9eOgYqIZvwBsKXmL71EXvviXmppGvV13n/\n+wXyfZ7meWdkRBxa3VflNeV41FplrRnB/fEQBDotEVp/HNRIki8gG1xTL7rw\ncy5xxiOM0A7397TCVdfyFrew39QicTl46Zw4kYpgJGmduz5Rz3ChIQiQ8JDd\n3ZW2svBLnctOCiItD2uUeKWoRTXr0CWI/RBBXzAX0d1NNXssWLzhSeAOwkb4\n9w7V8EA52yghc15QuFWJ3pLRnSKXfPo83ugHrzBdK3/SBzv+w5eU1TEl98Zl\nosRi\r\n=xUN4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIACeLjRLKXhZh1iZbz70bwHTTcAXi9cyRcgXIuSDduooAiBV2DmNJVPlBojeZ3vu+eEfrePLIsg04V0AMuQ6h+hVyw=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-29c4356.0_1587787535100_0.5745643037868087"},"_hasShrinkwrap":false},"1.0.0-5cc6072.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-5cc6072.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"5cc60728e3c680a2fe9a9b4b495b8566e79fb291","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-5cc6072.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-zmq8muGBoAHXJEn07pLJKduPi5kZ4+sIGf1QR/Gr6lIKUuhXXex31uNzkv7BhA0+Jwv1wnmeU1TLqo3QE3jG6g==","shasum":"1b027f4591e7d479cde826d326b2e67622e14687","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-5cc6072.0.tgz","fileCount":197,"unpackedSize":59121991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo7jVCRA9TVsSAnZWagAAfJ4P/1mAOirhQEF6+Tps4NV/\naV6chX/dM051tvOK3ySz+V0PyH3npndjhSs75azU9Sq6D2IlN9v62X0I7r5C\nCCyORo3+06DkE0vRlgHaHd9Gr96Caxj4HTnxnYa3B25wBiOut521uJnW5g3b\nobf02xZ2geVM2XCbzJz9c8tO/8Fl8C921j7KxhcAuiG1dgBZKpPM9VSl6Se2\n+gu++9IdstJ30QAJ4ydPF3SasJM/Pp339cGLFE6ZMPo3vNrgHN8+7twYCA+H\nCP04E7wyvJ4JsJlgh/IBHOjVQ/WdQuEVGRSy3mjYgpZ3VVk6ijYvh3HT6nZ2\nO8JgaIePpYr1EOchucjnNcl55TZr2mVkS1sNO/oNSIHbtZXmd+49jREpKVTr\n4BqFpjFqJWsZqxp9WzNNr8ZBZhKqNkjw86eG4dTEAL8czDel9N9expA/tcYD\nq79pENt9kZ0r5fppjZZlAoR7jQW+tvD3BFf0WeVJVFXZhe1cbvq+s+RKv1F2\nrUlhxJHKnABsmEo69xBUK7SR+g5iuzOxRsu+9yJ0ndxOi5YGCg6Yl1FazSeh\nOrnvFyDUraqbr822B1PfmYlEbGEXifslkfv80sUB7Q23Ck0lHQF54yhhmQOq\n+yw5+egEkzGqmN+QxT6lwuGAlO1ZCz+5HkvHgakh3K20S9Aq1Yk+wbczMQHA\nTwFA\r\n=j9mm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/HoUTgwJG8b354RtO6dLxtCMs8jx/5+kZvH37RqP2jgIhAPc1w0Idtg2qsAcvlf7i+MHItzgk8efHOoW3K4PaEBJu"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-5cc6072.0_1587787988206_0.018490027834681122"},"_hasShrinkwrap":false},"1.0.0-764abee.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-764abee.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"764abee9502b29ad30b27991c099bcc5e0ee1642","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-764abee.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-jYuB7lMfOrL8Aj1J9kVGIM0Uqyd1d52PIU7ZD4hUPBJ+MxEpRFdDbdCQJ0OyfR4NPcScTj4hjGUVUpgDa/jN5A==","shasum":"e985d25ae0cb6a118580ba2aeb5b8238a812dc88","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-764abee.0.tgz","fileCount":197,"unpackedSize":59121991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo7jtCRA9TVsSAnZWagAAsfQP/3KTV4rz5cdeIRbSZ/x4\n5SGkoikW2Y+wZTTZKVUqrSzWA0Tu3C0s7qBwGCIq4EQ8QhAAoLzt7dUvL1Kc\ns1ISl4DUWJMtt6gH93bHnJ1rnVENYKzHNO7zjxIGQpQTMsl1VMpkLRzJmYqh\nX2kxmRgSpCxJRPgnBRAWaLAISN+JekB3aVKN1EE7zbK7JX01nzX3I5eLF6Lu\nKfAl7zuqzZ7H+YjdiCY3v1WWdtLGq+sgVY94vpBdbW2fCC9p+6Xw3wp3b+29\nB4wbpk/+2ZUIQ3YwqpZdvR7HjOtNklkPxLUHKm2rrmrcG7SoVtWYS9GCpe48\nPzkUYBjTIy+BcuvwiOmvd58diCSwWc7DZT9YhnPvk+UW5uA0hxBIZyxo6Ljn\ncxAc9BrMl4f0HkuO2sgNCXC2w/ovrYI/M49QBsIYQRikxaX1xk+KtBZd6hFV\nobXkXmAUCLhNBSa4Et2ZL+nyoTTcB/NVzMcEzuHJCC49e/BugXCsjPLBASQT\nr6y7Bh0NvlHtW1UoZXy7KYUaFCZbwaJ0zprW0zBClbG1PLuQuenVuHFvperi\n2o4WUhMS1/6DzyUhDhV+uq5DXG8jQeZqaL2sLwDv4XQnCRtE2RyJzeM0pav8\nHmmdEggE5+/Xw9obczNsZ6pwNDLlKuXMkPrHkioJB4jYWYuQeQB44Beyjvs6\nCBTB\r\n=MKCw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCHyJ/fqx6bOUyl+7PqbmwuFUzZ9P7ZsvDxHWM9gkjSnwIhAObSWHNXbVgjlwjI/SwdpXqqB4B2DbR98HdfLj5uaqlJ"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-764abee.0_1587788012613_0.7608041078989447"},"_hasShrinkwrap":false},"1.0.0-4e4588a.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-4e4588a.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"4e4588a70b9ab4370fbdbf70079b070fac026943","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-4e4588a.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-CLKyiuj/V6gm3COMmRrbnlCzBAqxmD1inXoVve2LnpiL8nfyI9sJ9yvvoCBHm22ewEbNNWD2LdfbmiOvaulJXQ==","shasum":"56001e12ac51e9234f9124f7286cb9a6ee490ec4","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-4e4588a.0.tgz","fileCount":197,"unpackedSize":59121991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo7yRCRA9TVsSAnZWagAAHUYQAIyD5QkpoPa+u7gJZlXU\nAcdmt82qcD8vQrQ74MwVl0d7o7P8AYsaYJz0VMcPqzFuivBYwxvb4545tmLa\nEjQsrieCv9pr0F9BVQqRHAp6//CmtGSsly/fJl2FPq0FojnRgXw8uWZfFH5c\n6rMRGnMdV1tIGb8beoLPyx12vxCxCIcyrOZxNIltoqS1Dj2hTp4S0dpXmKkF\nrYcIhuCcVDn7ko0S00EwsUXvD1Tsxrsv2fQA2MEtm5UdocZ3seNcrUA+M03T\nrQjnY3ZVqqECmbbGKuWYC2t4WbBxGJWYlmIZleF2arL3V5PEUaGCBYepaaXt\nhWYPYm9659SfuF8ZAMtmFPrFy3LqDWpt0hN0sYh60FqOmuiN8fHSpwCMxLN2\nzh764ImoKErq8RjT2W57D4n76YQmvYtQASjq1vBieQc4k8I7fLcdDU3EU+gB\nwgaoWsdY3Fe12+mCcpEXtSz7BPRVObAyryO1TubJig+PA7pOyFl4+q/Z17so\nnBgbNtcxKM1MSSZKPPW1YfEI2dnYInBIxp0RUWMSNFcPMRXk82C3G5Byns2t\n9ChJTd+ZwdgZrpKOW0u1JoJYc7IlWB+uP8lM4RdWmTMc/MPddOLGwWWvdW+t\nTNu4vS2V9aL5JWxVvvOzZ2Jr0b4N6ViKpyurb8QSJIViKX8CZCJ9ciSGThRU\nEJGW\r\n=x8lV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+kR5I+UdxqDCBMjFfalOG6oNjfRgrmEBwc8FAvcAFwAIgd+Cztah/mopN0YkMOJeCvUywYi/Z4yDmDWRJMwZej2E="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-4e4588a.0_1587788935691_0.5899084596421968"},"_hasShrinkwrap":false},"1.0.0-30938b3.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-30938b3.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"30938b3d069400a0f0fd32e53f759e7a1f3233ef","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-30938b3.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-02pC6/ulhelZ/LR+wtHL6s+65Obk3oM/7ABSuzqrA/DS4aM3GVIcVkW+vrqV4Q10FNXcje2xaff3in8frhuD2Q==","shasum":"e6e3a0abc3f37afb6bd7a218c1a7de849792c8ee","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-30938b3.0.tgz","fileCount":197,"unpackedSize":59121991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo8CSCRA9TVsSAnZWagAAiP0P/1XveC6zXsLF55LTRTZl\nRuEO49VOm/hnzx8NKDiLMgUUBK5fRNk5e6UlQnQrcWvwj7qa+zX1HhkiscKh\nggiZcO13PFGnnQglLNDlmjV/KSew4rrenhqkNVBpg8KzBEqTJpJvDxWbWfSI\nM0i/bLA6jk4goTKtpGj0CKkL81c3kbVMh3r8dmH8UIG8OdZb8UL09+Bitnka\nzUjIu9PUsm8lnkAM8UdoVwEmCE3XGmhMwpf+saGUv/e94omkx2a6+om4S5l4\nPEPArIdun0QHPqhWbmypfx4i5sszoZfVVh2lYeQSIQIONlTy8VWgrE3G6/9y\n+AiJJf/9PvK+qXYUW7QPtY01yGqqeR9EoMZQ7zp0y1GEioaD2jI9D7yjbJ9+\nZ/tibCSM+qaNfEFjXY2xJgYetVh22BA0yarjCPQ/VqGD09TK9jT0CwB74Tqj\nfqew3aSNNMTblD5iy0Csz8ctcJ+8G5zNzsUUjlrgwwzTd+X+qLGfMu0cPh8b\nWY0fqn5kyTfAz1vAnAaTtaOUJ17uWPz8OkX4ujXbC+VDAjqK/VCkBD3WM4D5\n2TbBAxdLK/jvK5hbihYEyJHkOpZKF7ij6zTlVMuOyQgiIa9aPwYjfeMwnhXm\nf1zh33o2TxRhCJDLmxQvz2XNMNh3oNDR2Ni8xqCUrwunYM2b+rVjOT8Tqye4\ntLhf\r\n=qIOh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCIcHh+VrIS0n/J64PAzS6N6QTG6JQheL3reJSLFwkTyAIhALuL4zT+ZVFmkSVdrVwODIcHpikgbWSi1ABjE0xGoLvq"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-30938b3.0_1587789969253_0.45001738740377606"},"_hasShrinkwrap":false},"1.0.0-db8afcf.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-db8afcf.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"db8afcfe57eca6d10d53c507aaae36563e4fac40","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-db8afcf.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-iPfJTOqqvsiJFYIQsZr8ilRJLcQ9eGQJ/3X7wgEVvTkpQBMvSKSb/vQWHII8kEoRvYCWbbrgYGvnLzJ7YBJhDQ==","shasum":"afa35e73bf49d829a8db97c53ef0ec3c07ddf4b3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-db8afcf.0.tgz","fileCount":197,"unpackedSize":59081066,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo+eKCRA9TVsSAnZWagAAOm8P/RWIlQvAG2pamGj64w0f\nM/cL3V6z7tibGKL8xtuJsNSqsWlCBgW+IDk3p/Fpo0sF328fb8G26diBRtlg\nrVuGhfWcdlWZAGP2eBTAsTOr9fi9UC1lNP4TpmokWiBjnoyZ9i7GL1dl6Ou7\nT6kBLoCfHzcfjxxMMDI3jH8Rbn6uX7OhSKmYmuMVXQSso05flbeLlEW0fQlr\nRDWtLtrDnrC4uapgLVyvnYghtbr/bI8I7IGE8Tx3V7MbUcLoyxOzc+xQXbCC\n0L4UYzGFf5TJIkX8pGgriyLMi2zRxt6qEmYe1dUUlVe28p0uk8n+dZp0drdP\ngjFdSWwbnObsBDWudotoqCGKPXDj1kIFV0JYSPAh3ZTnSju4gmb8h1sfuq0s\nQIemSVgtELOsRoqrfmV60Ip/FhsOrud+vcxUH6LGLNUnp55CQRz43XYVz73j\nxM6X1Fzc8wKM6k7lv9Us/9PKG++6uOpjFhkXkbElSHh0Tv/Kd7im5Dl/T2uK\n9CB7tOht3b6FC4W3Chmj1Is58MQ1EF5ttP95UDmVIDC8w/rT++5G084s4yuT\nqu3dAeD7NOuwtpJnDmPZU98zfD8Lo1sXsXdFBIr6+K/K60uBZcSUlpsPnxsM\nX6+NneGBkhNJueofr8OgasV65D8qXZk3FZuvV/dlqJAxZ3V3QMkadrfBJSk4\n6WI9\r\n=8+id\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHv2AkNWJfOF7j+n1KOS8BlQ/uYMijsqtG3ZyzLCmiz4AiEAtp5/x9sLySy2QPpzBjyIAMg8dupfnF2YhI8RXrkyyRg="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-db8afcf.0_1587799945768_0.39626444650531445"},"_hasShrinkwrap":false},"1.0.0-9a4cdab.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-9a4cdab.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"9a4cdabe3c30453a5a8344c04b1a006ec20c17e1","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-9a4cdab.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-bOCFJ8UjnIowgdtp3N0lZl+2n+UX9SG7xyVXHIbMDOzEBnTA66IGvGtj1OJtgYvWvMxRiIvD78HDoPaepZ9OUA==","shasum":"40441dc70fbce6b69da48422281edd259f2b1b55","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-9a4cdab.0.tgz","fileCount":197,"unpackedSize":59099870,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo/+hCRA9TVsSAnZWagAApRgP/jFVwOHO7+jNu5QWCa3z\nmoVeVlX5IO+LA8CEHBTUUiGqPgq38RKXMAsl5udyGLPETM24awj+6WOr3vHa\nGpd71i1i4I/uNcaQbP0W3Cw0M6PIoHW1tKUSGwOliE0EpMAuwdMHq8F4TV+z\nOl6jn4ih1nO73zqamAlJTotRtv92zsc++2e8+3pXZ8malf5CYqlrruzdAKFB\nj1OR98hsUyQ3n7YByLvH6BFxODMVI5oJBSffM6ywwpxIFHjagG51mjusqMZC\noY6G4WxCfdvbif7/sHO1ES1oaLtn3mj6dhkM+xqMdNs6TW253f6b1mv8xFuQ\nb/sVFydmGnf2+PJEODFCYQgMZKN7GZsR49EZLtyFyzCwEWaaHNivYBwMhCEi\nvdbrODFAJ5LfrEwmJw9ev2nwYRDwUXcPGoVochhDqB8YZai9RRNNc3JdVfpX\n347y0UP4SYbjXR7tHNXMh0l/caREFLnIBATPcxie5mQzixEcEdJjKFV+HZ0o\nNF9qF7+v2EmMXUaUCBY4qfRPNl+1KbNNyLrHGYWyT7rcncJYZfqI1i9iRdBx\nMFhi8t6CWhQCYg7G3tVEjeCAiFE/2zOTGO6dfCKm0J4l/QNRh7tksQEejY0g\nLT3Un8lvSq+GEvOQBeIW04a3WXYKLe5j6dk+Qtnul8vVHs42ltPPHiIit5zx\nr0/3\r\n=p40k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFMxefmoPZ82ZrPzJ6ytpXUZMAy8n+62SDBF4obiQnXcAiEAjnm+AYNw0fmAwJpz+m1A9hKvGFS/WXR3GuW8XZpJd6A="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-9a4cdab.0_1587806111274_0.3491616802743982"},"_hasShrinkwrap":false},"1.0.0-0dc3b2e.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-0dc3b2e.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"0dc3b2e1925ac86c229e672ea85b27e5cb652f4d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-0dc3b2e.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-7Ggina+u1Dn8zjBNsqP/vRXwwtCP8kSWFW5XAr6At8m3ct6orhhjmo85syp/jqm9Psd7Oq0tmTiVrcZxbfiwNg==","shasum":"4520774362d7b96f8eebfb7ae04c1f8a84edb33f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-0dc3b2e.0.tgz","fileCount":197,"unpackedSize":59079505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJep8MXCRA9TVsSAnZWagAA+nIQAIch06P3IWx7z/ZhExZ/\nE1Ko6ByvhXphQHDEMpQ2NB1pvhLSD8FroESaqtJAbzlp2uQlwMUTkKFwWULI\nNgloyPr9Q2yZhQjHmSgJHFDsEjTcB1uuqgGfZvKKkwed9BgLc71zHuGPulpY\n/DJj9lal8B9kZ+7g62jmgSHltFzdyUPj1uatKEA5tLw/IXdPgOQCWxTgxEbD\nyvXHBQKXrQR8l9SBnOQ0FU4OMbOnUjmHuolvmvxMnyNU6qCZogoQqnpQD+Yh\nHpIZoHARlIk3QLbjWIBy3oE7NQ0h/WEleLTLpoooFAb9FDjgCrUW57pge/aV\nbUHPobWpQJz/cEX2lKzQyVuD5TYEr41lRIn2wARA7FO7trOsl9VTLbW7zlL4\n5IU+Y58/alIsDfOPLZHjnFMDjCdV0T7WxKzIbYQbRwKH9VuVWpggH0wm9nLE\nsqximRCzR15bTmlXAqAjHRtxg0rYe2lwsIGvWPQirFuTN2rKqkPIHHZnuHzS\nTjBEKVqw2x6X/FRYt0ukxUvWjACPsa2uYqv1Lrq0k4H7kn7pExhHwta/aabs\nLQLgYbwl3CHIrX82nBtRLgKspWtOROzDAQWY1mDK+CCTHfmuLScG8ZaH7p8f\nb5nM38JdFjWxv9+ofwI7RPqy9q14nCDoQHk36b930TWvyfqt06jXHUhLldDE\n3g8u\r\n=F3wb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAExxRE+lfAM7WFu8qHRGxpY0NJMp8UpMn4NS6NvcOLgIgLMIHuiAawaPzN+6Ke6mMVFPLO5MkH6C8ZIWZ995+Cco="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-0dc3b2e.0_1588052758801_0.564203495347374"},"_hasShrinkwrap":false},"1.0.0-3c47a63.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-3c47a63.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"3c47a63ac19fbea3699623a4135f28bd33bae68c","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-3c47a63.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-GCxWC/lw4fLXmfmBUwSpT97QknCii2ipfnRKpFal/dgYkEjFbpcLOPumbrPKDY83o9YCafe78CwHFo8jv6YasQ==","shasum":"25c1c4dfdb9aa446f65db5acc9c4069888aaca9c","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-3c47a63.0.tgz","fileCount":197,"unpackedSize":59034577,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJep8PECRA9TVsSAnZWagAA1wwP/0kknIy3X8m2JniadiJe\nMsb7PASnQLvgq2ykqc8AKriaTQWjw3O4rir6OMglAYWFzltxelvOy8txZml0\n7qv5R1z/kW34BUYxP1BRW393imQ7WlZaM7mPL1QVdXJxa0z4fxQU7BKa8miM\nW+LWF5i5B1H3eiVNFFlNGljiBnXkYf0I0uxG3pG3fI4MsVbH2JQwoMDKqUSC\nkWqXqjZnywpHPOQ8SsM4jtdJ+RiJwqQhOLkcSU3SHY+HM7h+KvgpCoowIuW4\nJzAycs/99yukzdE++f1jDh61o+Wfy8x1vgkXYPxZ9J0VqzU4FZwAdo3bHux8\nkEdkU8sSRK0KDTfjZ6fcn7VvbBk9H8BiWMV84c3YpK1L+8FtjEuAkkNCtrjj\nF4PzFMywkf/bummv7rU/2Svn6b0dgFlYIc511QpKx33O0DTf9jZ8UQ2IzAoD\nhBzl4vigOe5JhLMg+/Qe6Ot4cJVBufZmZWdXZfuIBmc4tRH1rsqfninQr486\nH+s/X0a0OrA0jv8vxlAb5gWlRV+MIAaD1ekmtAVimM6PFm3blW2yCuOB/N5/\nKfDtiucEUmMu454LJzwtpISIHRZ24mdo3NJRX1OnTVvZ5wWhTuXDLt0hgv3U\nPYaxdp/fsb1e71+h+GS5BlnDKkm8YKG85wPrDDGslJfA3od+xpdRgwLxqkZK\nPE7j\r\n=eIEy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxuwytWmNe+ntzzPa2kiYn7NTRENvfxfy26NtFEHzFfgIhAOqKdtKl+Z9iDpn+850lcA65IKpdqfvppMDnfuG2Idc3"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-3c47a63.0_1588052931786_0.7264253937570686"},"_hasShrinkwrap":false},"1.0.0-8859d7d.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-8859d7d.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"8859d7d843e36a989174d53e9d326a9deb2b0a59","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-8859d7d.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-51P5ITtsVM/L3URRyCaHtCUKZAPKG7ZLE8yyv8H38ZT8E9mfee11RsbswP26LZOrMFdKgb81XNjjhW1SN6quIA==","shasum":"6de3527040fe00baf511ae3b044ee46beabe816e","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-8859d7d.0.tgz","fileCount":202,"unpackedSize":59068726,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqS35CRA9TVsSAnZWagAA0K4QAKNxml/XXocygehKA0TE\nMz0j+qp9W8JUeFlu+Adc/8EyI0Gkqx8feUlr4LZXNWKc0q9DRFVB7ibP4Bbx\njq0eZVgXUkYGYWaO7qEkuQEW8Uka2temacDYGarHWkJHBH4T2HLcRbxylffX\n7C7bIadshIoon77JTbSKDTsgmRFVe7LyxwywdOAa2knB26gt4cQa/2wyKAZs\nPTO+hCjEwOU0cPEoJ7u8j4WfIj2xnW6wJA9Vj1Sjebi+N3kqUb/MAyFaSTsk\nnvQrbPyHSwloJM2JsJqUrGlJW92Fo0cEGGzC/tqtQ318QchfMAcVCK1L8vM6\nZQVHqB2bYKqYhlhbdFB5EBFK5RwQuiwDCX79e0v6UsRMafCHBonTYqS3/Axi\nIlR6mqKMM+kRdkaZaMZmhDHfnjkRB6lsALvpMcZ5YyFsTmA3W85P/lUoDzbA\nhAp+5+bUQUrp635hDDmUHsXcZJY4wjIBIdGKGFA6zC+3ZZ2JMujwOT32HmI8\nD9Xx+fDG5w2eCn1m/S3unGiisJwyjIx/jY30XbgvGOMviNDB4HtYaAOX1KYq\n4jHuAQwFsynjBpEBcqHkPTzKDSyfeRMqZ726RyDeSIQ3Xze+zQaOeznIEb+V\nSqYOwA4YtWCTzt6co2mF5dK8b0zwRo2ZmU40fnT/fvT5RJymuvc5uFszQ3Jy\nPdAy\r\n=hBY0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHXOwXJNGPQOgC8pLxSZbHow0ppbdPWA2X1g72FX7Pa2AiEAmw8bfFx5ukTNrprnviy5WBcIA0Gn4WJ7FfjbaIQADpA="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-8859d7d.0_1588145656219_0.4453563918124144"},"_hasShrinkwrap":false},"1.0.0-7d4ca21.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-7d4ca21.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"7d4ca214cd47cfb7f041c782795c2b98f3ffa858","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-7d4ca21.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-X4Jn0XMJQ9RLI99Fcu5Y9OGTPKL+0FdgAEF3FM5JGqcS974XAuQ7kSr+8aMyOAU5X2BbAJtp6rrceiMhiQ6A2w==","shasum":"5ad77e350bf0164a96e83094fdb47c198bd5b26b","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-7d4ca21.0.tgz","fileCount":207,"unpackedSize":59224845,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqTNMCRA9TVsSAnZWagAAk38P/0MeRX2RMN27UI6n2YYj\nneV8MYBj0bPnhZHML3GecsYJ96R/VyptOjiP8qvdVL24d/KFf1cuATfSD2ck\nCXfJ7TPiH61zTYVwdPsx+MwhoGOW9ZvnakXMtxUpMb6JkkrptF5u4Cg0MrjL\nbih4yYyBzUeod3j2xATbtiM8kPzN5dflKb4KzIES6CjgA5wuz2alErNQsvFO\nKqzxqvuOiFk+eO59ak0tAhKkuAQxiIAJHPVGLfCohN7sIummoZF8hlHY95eg\n0aznmBzeWmOV6QBP+Xl72UkbB4ggkjHOP4mIhJwkpREl9eg+9UsNg2qVP495\nRalZSuELA8jDoT6Eo9eymnXWmmhA05r21FcGigGNqvrd3KoiGpKxaC0XCCLH\n3klBQsNji5yY3Vt0oNkJ4iS85a0l/os/gJT3ezHSDL25mBehy1xxxPbxeN6Y\nQ0ME6KlTi8fpRzIJ91dfqNa5UUWkxQ3jxYqqjS6hF16M/j6ZaMRLuV9LtDg/\nyJhKtOu6j3vJY+sw56gKOD/a55bwaj1c7hARoVuAneBim6jHFjjJk9eWxhYV\nAJgVjt67Z84Iz7V2X5OqIy4bc5Y1PaSNJ6eWmtMrhC0wEV55PnKjnbn96hA9\nVO05Ynvl342mrH/S9oZ8oYqKa6t3D6xsG99IjV2J3JEqQVPmdnGxUm4XNlM6\nDQC4\r\n=Cc+G\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD9PvEFSKHpbd31sJx4AYhZyZ4L4jx98tBBe7GliXxGRAIgBpapZV2pcxZpt6ljbklEng3q8yfqk663hrTGfAvZBec="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-7d4ca21.0_1588147018839_0.8266257633036247"},"_hasShrinkwrap":false},"1.0.0-df4bf4d.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-df4bf4d.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"df4bf4d525b01c28212283cc5025bf3bb3e3b75d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-df4bf4d.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-hlAvmRti9/ul+4x/QuHBq2dg/Lyzt7oBlWenubUFjybNduWHVkgS7AQOADTHdpB/5FInoKAILjX4DdCxu0Grhg==","shasum":"43108685adca50c84b5f47d89c46f81a77eef367","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-df4bf4d.0.tgz","fileCount":207,"unpackedSize":59224845,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqTaeCRA9TVsSAnZWagAA7AMP/0ykAjzKiG3zEdIyz4Us\n+WPTWSq7Ktwsu6UoxHdB4r+F+d2Tc5hyG3iVRN3X2ish72wqb8AWfS5pId8A\nMjvDYve4173jHpFZVlhctRKWuTOVV7cSh7zj7Lgatl0/iD1r+ngZA1Y8aaYa\nVRgIcqh1S1hZ2ggp72LBkrlx+EmlCXHSrVOdK835fgnYuL3+1wfoG7YG7God\nd0uSfNZQBKqWOT0fSwGAeYFyYTpH1n53vPW5LE7bfA4VwDdP3pDkg4fDllUp\ngy9Q59DOqAzbrgqLbUmw4eHuI/KjWJ2PRLKLP0bazjFRLfW8MBEE1M3ec9wB\nq17sWDja5eNkvsiEJ+faEBpQoE54jmI3rUQF5QKtCmOEswZlS6cRXk6oDLYI\nsoaq+NNpy/d5I5uALf++SPJs7o0aDjM1jJOe0sNvi0aZ9Z+ZnGtwVIIQIiPp\nJb1Fxtyh/fqNlfi7xAqae/iVi7BpDirdE9yQg0Wmx62xdk/E8yiTW2cs/lnj\n+hKhZLAskA2C+YTtp9EKP4QUadNUcX9ux43oIwFpEF1gYfKPnX1ESqCFfobB\n20TTFB4f7Y26PFVd1Z1N0LhZuLwLWuJswEhL5f+VtX/dAQ20afaiZF1z8LVQ\n8NDtaHpn0JAfuTbUGKu9BT89nFcD1oAFf7d+3irWp43cTNx5EBI2dsG3LmCU\n/Zdn\r\n=irZ1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDBKv2wvQFbcQgopqBwanDvTdwn0NFnSkd/M4io0cuRFwIhAPNaKNGxOebqXmHdnez+ignDg6aIHLw67DOQAiudwjq5"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-df4bf4d.0_1588147870078_0.432241043572948"},"_hasShrinkwrap":false},"1.0.0-fc30336.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-fc30336.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"fc303366c85c96feb99945ec4ec8566cdf07501e","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-fc30336.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Ouoz1SpaT1+3lhHHwvi1LjfKNS9hCwPpr40w7TuY0WGtFM0e3+Ot9RACfw2Xg/7qDPU8J0cI2F3Ow2S3e2LwKQ==","shasum":"f772e90b20908e199c4f03af448fbc1d6f1419c7","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-fc30336.0.tgz","fileCount":216,"unpackedSize":59228580,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqoDCCRA9TVsSAnZWagAAc7oP/39ETwpktsRrX0/nzL3S\nSKYp1shAwuqvPWA45sQrkN9edg3VSqnOo/cdNbmrcPBfQAM1mtwpqPN/LCeX\nX4ts5HStsQDbbOCi9Y7tAgq1dt375QNzVfTVPzOIRQ0I9suKn5a+hIwJFiPf\ncYwccw67ajEOrXACZQ0gwfnJKt0bOES9+pNIJJlL03MmMu8jvtRpdg0tiC4G\nDZcTumugKmqCozSa0ikenoO2vM6xU6QT2l+HFpgFYw4IikiiKASvaWZJ4A+t\nxza9CMcaIU3q0nIrNr7ztAGvC9DhpstRYTja/PQO8/vjUHvuCH0aCbL/QCj7\n/CL7yc9tyVxwn3NM/r7YSJ9l38VonruC97H05F5a0UtKSdMlZGQ60jbLMF8f\nHIodhnNyuPA4ssQM+KTvNeX3YT6+OnMa87uvvgW/9XY2WKrClJo9TQluLjml\nmUibinwNUaq38n/nnlKrcfN/zTbYPJdC9cA2EbNP3ZbWTotb0m9J1novoCGM\nAvrZyMFOY/Svvt7X8jSlr+Syc7FY3SmbRngrKZPi5wOnW6HhUpRytik1NJiy\np0IwEbwevENFf+zOs47sFZe8m5JytpdcbTF+3uvEOfdLlKGEWxNP6l3S57UX\nkDHac4VA1S02hGsEkLzaXLVw5X5B/66lwUVhYoGyajxkVn+o63fB3037KGq6\nGMfo\r\n=iSXW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpNo57KMSf4RK2FrcpOFKYWwiBn1Q5u080gMRDpzBnsAIhALrS4LTcHQ6QrAgHJmKf68dKfiGHetVmXz+AMEECAKBi"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-fc30336.0_1588232385192_0.6969760468032651"},"_hasShrinkwrap":false},"1.0.0-3816e31.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-3816e31.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"3816e317652126b316b5b6706ff3cd92b91ff426","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-3816e31.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-1BdEVC5qa4US+nTwlkJmadDQ9a9PRTvtTWha8qZgpER83UzRnRNc2ENIVaimZQkSo84Y901L2+6ZhbbS9Ppsrg==","shasum":"c9d22843f2e1a9f3867c7785e386733061636b21","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-3816e31.0.tgz","fileCount":218,"unpackedSize":59252412,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeq5FNCRA9TVsSAnZWagAA7UAP/jVYOGhTX1zqMAyVVwK0\noDod0I3p5jFDPnqR3OJOian94jg6jSQEVA5WjfVxjo90G4xvkIc2yqXZewG7\nYoRvnP19pukydca4uOMW+1jqL7IqHpLxBkAMI/F5467w5v3YY3ZT95d36zQR\nKdVcrrpfnlIbf/inmaEsmJ1w2vBYX0+/S/JnKeEEmSHAfeeY9bw43e0xNWmV\nLxTOIRujhLQEhAlO7ym+o38fV82oHzeLlf8uj0p7Z62Dhn+poPucn0gzlPy2\nesNwQIbGc9c6YR9H7xJPymrrYqPFLjbtiHlI1oobuezDFhQ5I4EvueTxmlOH\nsG6MaeeV2cOJpCA1rakxPyV5ZaUcL1SCpekUsDFhxI+8sreRl51NWT2u859R\n7Of00RqUz9i/pkYnVO3Xdq7cNc++G+T9NpCb7LWUphb9o5j7iv55Yk8kBDB+\nVBMKMM7t68VK+4pNf/hXMUhIIKPK2g8Qjn24V5CWrh/tRHSG53TUXMtrile8\nSHGmUb8R2D0NeT9NrDfLwMSQZmLiOha7m4OZIRebgXrotfAuuPxULrPUl2Ev\n8JNl28glUlmtLJc4fXFhvzIkdFDPojTRKp5jJoRGTwKhydnUKVJ0y8MhWtfN\nvhFY4qCAUDaeNRJtdJsDbH/mOi5JIpOfFMQSXkml8/ztuX0bVne7Bv+7ELxr\nVO3X\r\n=QDEc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGMptmsGoKgn3r/2J0XAmEd69Akpj0QDA0dfNNjuqFu1AiAuHQe1puYiw8YT56fV6KvwY6WabpZKfnzELYpD1O1ong=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-3816e31.0_1588302157036_0.6705602696141817"},"_hasShrinkwrap":false},"1.0.0-ca361f0.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-ca361f0.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"ca361f0d7e43eee3fa085bec4747a01fffb667e4","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-ca361f0.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-riPeH7tld3+4kNl17kp5b0yOnpO7nGcU48DkBfTs/qodxcJKmzm+iSRg859Hlk2rWGtuqhC73SobpYaltGxRnA==","shasum":"a259f895856fb9f39353d197260a3b206e403130","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-ca361f0.0.tgz","fileCount":223,"unpackedSize":59265715,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeq5lUCRA9TVsSAnZWagAApnYP/2qb3eLMH1Tg7pO3Jv71\n5HZ+F1VSY8SLyraqxTe26Kojal2tzZASihlR+KZV0crADQpTVX5rwrMbF4Yn\nAGi5liAGWaSJ0IWi6ukKt2YlQRr6cdViePFaKgaifL5tUTg5ORbt8HbGJByW\npt8ZP2TIE5DgAAzq4ac6Y2QGNZf/1gcpWd0lCW5fysPa9JiQfd2d6qP3t8RS\nS6MbQCxl/5+4tsJ/eO7UPSUoAiVacvfVAH+gX2grZogZhZDmD0N/TLPUVfJl\n47RkBi7hdrQPu5NkfE6D7zedVAt37HvKOgUbrQtngZdqQRHpTpNGI/6g6iVC\nQAqehM5uMrLgEcsCnJwD+k5kHgn2/cFNmiMD1R5HxCmf0TFvo5CZdkfls8x4\nQAPVuVn+cs7Uh5EAOHqmAu6pIB5o2oc8Cs8o8FRrnfPJ3r86Vw+6z0TpgmzI\nUe2SfhybuaM3vEwVguYYcTe0wgVTWxtpyevdVBrqqWMrfEdgA83imnTAY8kG\nGe5/q9zjuQPXehJ2TwaCdyWWERKFbzPAfaljy1wKAZPtA8iQ8BcwXPbUF2m4\nwb9bPp7oAXPy359ircC90T0uVa2CMfUVLVEvpMXOQpLfj3sRrJERPGfSxI2m\nEV/kqjBItRvArJuF29lDFJrUlRJ4iH2KoTRPnyz9i4L3fJu/A755gZHCLwfr\ns6lj\r\n=08+O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEXmBCyshg/ZoOYFTe1On/o467uAGwYH8ji1qIKNOeGtAiB9RlG+lXFfZmoN3XUAlp3v86xPQlxPlGwvvY6dezSjYQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-ca361f0.0_1588304211503_0.9422009396191975"},"_hasShrinkwrap":false},"1.0.0-cc559c6.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-cc559c6.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"cc559c6d9e0b16596eb39f644a2a3603c3555145","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-cc559c6.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-/23roFnsz/X4D0cUhhj0Yyx/WNxh7ziK59pyyvbht1H03zVpvtvGDcJK1rT+vHZ50JhrWSpVGGlXkAVTBASIig==","shasum":"2e414d3c0b4abab176831e0e588e1975a59c4613","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-cc559c6.0.tgz","fileCount":223,"unpackedSize":59350366,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerM8zCRA9TVsSAnZWagAAox0P/3EPOUaFfF/904FDw7EL\nmWE9Gs+2L3DgLnD6PpxbvnA8xc1gXI6fP7dYXndh12AmBXMwXOAs7HO79biH\n1YoJ1cfEaUB2DW0WnlLhm/bpN2NFJm3noSmipGr0qEwCkTk9JxK/7a4DM/XO\n6oRAUDJaG1qSq6sSLPw2F4Vhisr2sPpb1vylag4fbaFiOSBl9DZrS7xkqe26\n+GcE+W1WK857L+k3C51ArFExpX4YuNgERRw00I+86jIA9HCPM/AktRAInZp6\nmbJI8YOD/HQkyRELdQZmINyY2gzZeK5iZ26QaBcFcRxmRxpmTXEMxlqIpJjW\nNj8bSbgbjomcBvIJwf82N2oEfoDYVVR3Xhi9B9FxxoVk/GqfiYNr9uodnsOS\njbUAOVqSn1ombq30a8dhzeK3yxD3aeoIKNb10YMKAIPEWZQIWduE891pfCEQ\nf0q1HLFP6f3iav+zBKdN9a6ixO1UwZJEsVng65AbUFfRM8+K+OQYrSA5ju32\nPpG4wB+wjwV5PpDnNUmmrRsT/GSxENe0cns5iH8nnFifVPP4l+WA+MTTgG03\nGMQN5RFzZCz0/Pua6I3AEXGHSxuib04uokuEQxkmzBg65zqPA/IBBqyfv/1J\nEYaPs0Z6r7fWJIzx4sxk3ndRs0kJtp4Lp4OOyFKmVQAYaFeQFOxLkaonr91/\nYtZK\r\n=Dzu7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHnQYDYMtKn5CdxK91f+zDGKo6J2Etzynk3obwXwIq0pAiAnvTbxfpVsVTcXplJO5JLqJsLu9Zy/fHnjpgrcPqHrPQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-cc559c6.0_1588383538989_0.9850598531101271"},"_hasShrinkwrap":false},"1.0.0-5a28b89.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-5a28b89.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"5a28b893834a803fd762ee76183352e8e8675b64","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-5a28b89.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-u0QFJFpLIMSONOdgYcNut0gQPDdtqFQP2XX+jcS+oK7e09k2Vp6u20vgs/lZipj20vmw7ZpUSLt4Qf3fwy6Xvw==","shasum":"9543649841b88f699deb813902fa8bee671aea8f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-5a28b89.0.tgz","fileCount":223,"unpackedSize":59348874,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerOJLCRA9TVsSAnZWagAATC0P/iXgyDY3iYjHN8NClCW7\nadFgeI/fnxCeK6qpcg0e+ylY/cVVriIa2bcsRJKdN8rXleTgWeFCPp4WWwVf\nRZpFmRnPrAR6Rp6LuqCji2a6KL1bfiFT730C9QuFsmPGHDbAarxqFScgf0c0\nA6C+F194ojqMwiFKzblLCGRlxaRAbW0WGB3JQJdMabiGrGQzKtqv6zjpr9Fk\n0JItlcvyZpFRRm9Ob54Exss9uBc43zNIyvxefvrZsGVZsDBcumJg0a0Rc4I6\nldLVhubF1HzYyjwWeHZbqHY7XLVCFuJ4s6MH1aR+y1VxbCklG0jX4inSxQ8k\nackrYKtFsQz2YCtA9PS+uxzL/B+334U42g1wWBSi8ca2huh1CL/V9sDgcAq5\nf3+TwQRknoPTei8xy9QnCAXN2k9BbFhRlvcZsy8M9tojdoJZabdmer6LUVpu\nLgnqm09bssZ6R9BQJZ348HKEj2SuuB7YL6QfcKb2mF32KJgDFjD1zI+wRzsq\nJtRL9yV4gOFlSPT4W1RUcxhjx6Y5HFk/4VVRovv5TEos+hBH2T+kQqsF2s/o\nfJSvKTqsm50MNDFyYpoGnmrH0O/q7SR6CsjcDQy7Y8U2Bf/JnraelSiGhjUQ\nR0OSkd+3ElU6m53ibvAtaRgUFiJR2O3xLcTqOpqC5riEt9vJmBd2/RJYlyKp\nE9Ed\r\n=nBI0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCEsgOAwXPZ3zL6aXHgQT75sxmoz03+bQMHlyTise5bnQIgaRaAWZz3tL2KwHG2EJkzk+THsQU85zRNpdgb0bN6eWI="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-5a28b89.0_1588388426071_0.1726315350523353"},"_hasShrinkwrap":false},"1.0.0-f3a059b.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-f3a059b.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"f3a059b127d4c5cc61a2d2938976d3f7f67e845c","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-f3a059b.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ZYEIiZwJVhUVgyPHwrW/YhPms6Tx7BerCXwwWUO5/jU9xLV6LzvJQHdiTBc6iYpW1ZcswbqbVaBgUVqnz3Od3g==","shasum":"43f032c56e9a8117822de246bddc7a3879e2fc67","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-f3a059b.0.tgz","fileCount":223,"unpackedSize":59403577,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerOgXCRA9TVsSAnZWagAAbIUQAIfIgeQSVpDl/w2j7OH+\nso7G0/jMMEXp471n04xEg0aI7JYgMuZagoflhFrio1QihdT4mef0v6FBgt8K\nuTO1tyAC2g2KHOZtVDIhS5C4QNaSRDTPbAXqZd8v5so/fcmuy6E9jDaSLiTY\nkBz3Ki43WW8W7bCMYCJrMWoF/OH85pCXel/SGOcPVWA1i/wrsyfyT2p0v6/a\nrYwNV1Py8u9AlFAUEMg6rvIGSN7k9q1nhrjZ1ErHmnpaLVHJ225nfUyXh11i\nilwFGbSgON8Mc/wfBrmpjvtNwCdMUhca4+GSbBbpyDII6S8oVGO665GX4chx\nLy8tGeaoYunKPXifgKaRveKYh3tz7n6rZn81NyyP6gUlzy+HGMo0WWogKTN/\nu4wVusCE/s/+rkrKDaBSl/Ay5w671sDxNlJGhcmMJjFUq3yBHw2Mz+kKCOf1\nlYamEuuGDqCDl5LvjodMSa0ez4GwLse8mX8lGAf0CmX5ZrufLAP8krOL43wD\nw2rMeVPQz2ZAMgc1rKo6PDvfYXR1sUNRWSrcQ2ia6ZgYtilKSzbeibuboCHr\nVKyPbrmZ/k+/ORJaYNMv8JSLwVG7b3pNW/trEXMSVmjmAxo90lQZZhdC519M\naTHuSFXDusaLBB1FaRHKjn8ut6GeRkhMxY6CsiiWj4QoxGEwJkk4xEeGrjbv\nwgOG\r\n=3/4y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHWN17t7labSPLKkNdBItwMyF6QoaV73g5W8ETnaKQyPAiEA0WJ+5rqRe0ExiF9ozUPLV/lLQdre25zexrmgN4/RKyw="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-f3a059b.0_1588389910350_0.36009789792145797"},"_hasShrinkwrap":false},"1.0.0-70fd977.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-70fd977.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"70fd97728731988fdade34ec90e45328288873aa","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-70fd977.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-f/pkJdc/42KnLcVMienwW1r3YrfRaFxQYiROqx2qflyDrAg6LM6xeyGDATejVlGtTCH4Qc2tL573Zh6A147Juw==","shasum":"add138ad76c9a3567ee338ce575e723ec3d87b1d","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-70fd977.0.tgz","fileCount":223,"unpackedSize":61050293,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerPIkCRA9TVsSAnZWagAA4CYP/3dDZICp2KDlDasezU6i\nBdivigY+58xjPP75lvxgL4jvwAliAtKPJU6Z87jCYEHilQ3XI+OsgHGNpFPK\nLgv+dwpNfDdSs6f7qPZZ+0bcgArell18E3YkI66xUQrmCXIO+6zhT9gbicRc\n1JPcsQ2TmYV0ZpxLRm6fTQMLFCILL0KZOObXSgIjbhc4gXqjVpzRjmg9bBGI\ntKP2uP2by4PWg8RGKc0KrKlMx2JdNcVYPeVxyvOl6FkLCgI80SrdahAYzdQG\nJ/Zssc8DhnaugFzcxJwaBo4ppwxel3QhWPOwUL6b8+G/ty+IBPTY9IjIBPNN\nUp2a13CJ3lPwAHoj7KvZn1ZYJUZ331iPuLfKeUqAXoQZm6cgMQwRzCvtXfWF\n863TqcY1GvQBqpa4jFaxJIwuc4P/OpNHPaTy0Tu9FQl/i0S7cr96wlbiolpd\n7I+xjjyTbdZlhMStdaE1b+NT0XKdBWuUz6+kRneT8nVQiaVNsnYgdFY0nSRK\niHmuKbdIoxMEm2BTbsd+wLLMrTfXhrhquRI+6xgxIDdGhwz+1afyBJAA7Vlp\nEFmZ5OFAjNipYThdNSVHNardYUMAia56+EkLkhyLzQHWzwN8LWb0qoDKvl/6\niKQ5zXBvPC5Q+GjvQeGR5iQxZxFY796dTCa7FTajPt5MLsLSm90XhZ9zHZI+\nfqiF\r\n=kooS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBxUHwZ3vxP2JNCHr4O/vPUyJpTQZAL/YatRkGbj7OBgIgeoeXf01pBiLwddvKnaas9sSZKpHAzqFdU+SnGtyuB/I="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-70fd977.0_1588392483644_0.28348927905496324"},"_hasShrinkwrap":false},"1.0.0-8549e1c.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-8549e1c.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"8549e1c32e16b12595a14dafe7a71451a56f1024","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-8549e1c.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-EPxzmX1qtJFqLR/zcJtGHFQ4HjqzG0+yhuuLcUjqx1jN69PWEmA0BbyBewfw+dIDuGWAkmU5y3mPXdC+srDicg==","shasum":"b7e5c257186b4a96c127b8285a71ce55d11d12fd","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-8549e1c.0.tgz","fileCount":223,"unpackedSize":61048425,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerPRZCRA9TVsSAnZWagAAm4EP/iNskqpK4LO8Ukg9YtE8\nasK2xxYBJKu65s/vS8nGf84bH/l/mpBc47wQO9e6fxR4nXgV1f/xI5t4BGH5\nK1QHfZRVt+CMZCKJn5MPBXBnFS5eHqpiOYHN4rgHT4XYBfDh9QXG8+3w4/gs\nww43Q0XlTfND2g+N4F8Hb/t4jBX0ZmphFNyddfRoOKW86wZRll9eCi78v+pN\noufIsdreOpO+/TRFMDDWLTDZoUtr8ISgsVYSkW2H4YRNIbjWQklyALEb64mR\nq5O7W4QIWO35OkyqrVxZZhSfnHo9P/wRGZig0Avn34IUwKpeXXRGyGqwXWUO\n267UcGN7DjDpu9shkOnqCF2KoecX0AyHERwIvOP5l7O2bjjVbiGOsKrPgh3N\nuqTe8iwt4jhdgZeaqeL6gWY1LjaO2d9N3epREiFh3KRKPBS+eSH71L1EwS36\nshyH0JzufMnlrEflvK/5ELKGN3G7VjjhWTRu75j60MH5n0Bq+g54J5dBwkZt\ni11xlylkG7PcPTi0uvYSc687Bwa6vKydJdLGzsfFZveNmrp0bQC6ErTo/0Yq\nhaOLNoy+L6mgWHpwoJ2iQAvq7Umrpb83V0gCapTTmTpXGg5LDVPb7FuFlvvM\neV56yeyHYv3WcWcOwxfB3an0qJSFbrHEz0WkNc5Rj064f4fFhm9iub7Cc10D\nR88M\r\n=y2HD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCZAU46xiVBFuzL7+VZoR797fLXtHGAkbFyMx/BRyVvYgIgV7mbF2KleU+ZTCcNAf6u+EF+qYwThRsWqOjnLIy/bLw="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-8549e1c.0_1588393049113_0.9355228498699999"},"_hasShrinkwrap":false},"1.0.0-28bbd85.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-28bbd85.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"28bbd8575f1f281a514457a6966384bd8945f410","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-28bbd85.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-HIbpshBmV/m/YRuuh6b1j61x3+kzYGZrTcQoeHc9IFPSU/x3M2E+xf5l6h9g21XT6G9aZT2PND0OCAnWMoVjBw==","shasum":"1b44cf0bbf91ccda8932756580d66886ff64b8b0","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-28bbd85.0.tgz","fileCount":228,"unpackedSize":61059264,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerPn7CRA9TVsSAnZWagAAHHkP/3rHUEt4sxLtXRL/lQgD\nGKkSblR5DbCP5TeaA3Q2hpgBdMMEWpCpn/Qu2VlGOwiDGfJwcA0WqGdbMkDR\na56FMmdI9LBXvQWMXH79W2CE4vJIV1A74JiHbhlZ7jmQxLhyFHUvTY9Po7KR\npM33vfsLh9vYlFyWVXOjW0RHcHhvyx9hHxdnpK+Ukq3iuG9HiQd60RP+ML4k\nDgs1xtlHCH9jae+3KTbmrz7kMTlHCdRT2Ypt3pYl6z55l4q5NoFzNhwwcZgX\nIOFu+hKXTWwSUsgwf2uV4WlY76jT0VL3iGLy9H+/oyd0zRm103Lc2fbLJMev\nnyX8ck6Wmbf4Xo0aIEA/jcNYJ3dItObelVpyvsdTXmxOB+cH/F6v5M98RcoV\nDIDq2B8sa0IheOpsyQbuhDqI9lP8BGXN9DkcrB2kwZGdlamPv9hY2jiwVvcM\niAwQlD8mCk2gsU9cS6S2mVK56qsvShpJfkMckNfL7HI/wIzRokw0cJ+r/61b\nIsmlbMqDqo+rWIJGKr43XMjnNdSlk/zG0xTaouVv7KPB+8ioJs0Q7BVa4v99\nF6KCiXBIVPpmdl77A4bgCjOARv1njz5/UFAZjHEiqGt44MpT6KrAPYQPh+JX\nxfkLbgiGyuBVkfX/JzjnxKS8tTHDMkgrC/Mi1lYu4Xs/YNUuYTtJCIHHXLLK\nbyiy\r\n=5dbv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE4VKKAmCzSM5e7B9GJH7mbe2tjFnND4OeMo0BX4p9v6AiB/eXyOWnjknseMO6AhgE1FMTWbh/rE2WrPJ+eBpQW7wQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-28bbd85.0_1588394490859_0.02388571964062014"},"_hasShrinkwrap":false},"1.0.0-6cb8491.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-6cb8491.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"6cb8491e2fcbc8d72ed198b2df3e38b0778af1f5","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-6cb8491.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-wRvyZNs7+cvaf4QEReuTQ5BxF9zEaDzSuq4LxrP6Nt0b7Z9vaNpO6l6AN3h/X771Z2Y0ATl0lhNk1ZgXR3gjfQ==","shasum":"cb13a2dfa6d8b80883d3696ede66be578caee098","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-6cb8491.0.tgz","fileCount":228,"unpackedSize":61100964,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerqHcCRA9TVsSAnZWagAAhg8P/25H+nnVl47/u55VHJDa\nrMMSOLf6oIY93x3NCg+HNYzXGrcPNg1CUdyIDi9SCQm6qpI3RDM3C+K6zWEd\npfhIZBVpcZIPBZQy+UCbryMOyUK0p1ZA2mfbHj/YnrFfI8GvtOkpgP98x9d/\ntsK3grMy8U9SniQkyEre1ouxsEsAB1aJDq8OkPfYK3cL9Zb3skgLOiPACnVh\nsDp0DueVaCJ1uPjYahtUJCD6dL0LESETSz9Zl/DhCXbUFJapv9MtxkltdHxX\nwFsTzLgQk5++dqx85g/QIQx5vsxOIJ3y2LYcGCUfFmZKEhcWxOC/RBWbhScY\n46dkvvB8okPVJOil+XDcA9qw0et1iixj1dGD2A4o4BdzmRx5J/bi4vTZ6I2d\nYQwL77X+gTX9Vfz9AG+MQHA4cQu5A5qI/m80JIU92Rp9jfF2jK2VSlyQCEXT\nYiPBeAP3JgP5h4Ucgl4wcixwwaS42yagGq3QeD7CDpTtu/LPTF3xixNCme0n\nrzS9xQA7UUW5tIvUwdUqKn3Wz2g+mo+MOIjTc14XeV/cSouU25MTRJ03dPAN\nMvyJB3HTiPbT7RBY5WL+jtm3qLHWIKCLNJRZ/9xlfxXBWP1R4fJ2sqbmlzw8\nBjImPY/ywYAAAt8OWX/LxHMrH2GVakw46t0qQgJocKaPLKq5vACvJ8UzJ3Fq\n1ypW\r\n=p4Hl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBV5bK4PprQiKL7Tq9iNRc3lxZP1F/GkZyCKalbbqxxAIge5ouDSA5fXmEel0xGAqXysTNRgSv+AzuK8K1vW8A0kA="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-6cb8491.0_1588503002963_0.267526518518441"},"_hasShrinkwrap":false},"1.0.0-d3088b2.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-d3088b2.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"d3088b2742c637b554ea3fd331c5f0f6b684870d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-d3088b2.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Px7zd3BHTEiZyFrNlfAAylXeLM6+vorj3GwarLSgchJx43IK73ySErL5rHxPHriHQ78e1gueC4YE7Ufo1MbG1w==","shasum":"ff45499363dbf5ce624d6bdebbf167802b803899","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-d3088b2.0.tgz","fileCount":228,"unpackedSize":61100972,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerqMrCRA9TVsSAnZWagAAjiUP/0dgQpZ8bgldZ/XwhF9q\ndkXi5MufEVyNdEIANZRChJhvBPPbe/D7UYuuw8+pHQyLtJFwpLohA4rCuPSV\nedGTdFieP+BWREeik1eaeMERlAGDzfdvwZ8ifyBv2Nv8MRIqI4K6FR3cGMah\nRkTRUgumUVvi7AhVJczzVTr+ZnvvYV+fPVHLJVG+SHb3nMonzJpOL2qLjwxO\nMdUhEb55vO4na682iDQQfQ9uSs238apTtHngITMIJr1S3fgIw3ZUZ8jnTyOV\n+AwG0BtTPT0BEiQhY5qwg0OZp8xVLtuLnsK9BEHw85cpMkEjF0e/ijKsfIh3\noPptufV+XbbJ4JCQ5dVnkYDjVu30b+lUAG7rTRn/Ly+N++PRqX7Wb2RCzKqk\ngLR3k3yTqvD9A6cRjCMayDqmpw/k90uO2mKhzP/F8tqtoJZADiLWoW42oSCO\nUxTe5WDTGFOqTIkJ2eMHUvKYoKbwXmk3MvyH2FXoiaftdvV/wNjxoX86ZP8E\nwwDUYBunJOqJkD6Wqtv13YKrXIdoIg3+d1RA6MtykcHXVL7G9Q8PwA4SMEQU\n7NZB/FBtn63ZMFkDlDABKpBt75b0NgAf9DelSQXTaTllDN7yvF6ia3B2pFRC\n5YQTfog3v7behActreXYFDKHDo+wSmdddyqkLMf/3TDtBkHMmCnDaGSpsrYG\nSU0X\r\n=Mwbg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAW1TG/ZkP2KoXIOiNjW2C9ciZPhBuhLQ+UlQUzMoGYeAiBZHfevFM4QxMtS+UENCRZQ8+lTQVPVpZjpmMtTDRmGXQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-d3088b2.0_1588503338640_0.34728432333193626"},"_hasShrinkwrap":false},"1.0.0-e11fb95.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-e11fb95.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"e11fb95b5a6f07a47959eaa1bced11381de4d7be","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-e11fb95.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-xTZjDfBQUupI/TOCsmEM5je0nWUHcU7yFLeSdBVbArpLoeSgOMlG83SLQbLeatuo6uuDNZMtpf0Of8MKjAtlTg==","shasum":"4818de24f381032da9f49c240f57461d55276eac","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-e11fb95.0.tgz","fileCount":251,"unpackedSize":61198355,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJer88rCRA9TVsSAnZWagAAVoAP/30RTugpYWSIv4r1cJb0\ngWv/9PqMZBYWO8zoWi1M2Ti7L8a3fpCo6jbAc2yUTluLhJsGbMfy+cPUzonp\nLQiuh9eSUz1JbAG4HWxEF21RGVQUIVba94gePr7YRyoJqrHSUIprl0xT9lr2\ncDQEIjIjF1gFdfCZBMB+dtvUb5qmnjSNhJMBRrbGIfQ2DPlCKcRigiVRAsUP\ncS+RRznjLTaAcJHqtB16FnIirSam2F3JgFLnc9TwcdnGRn+othmrs1SFq5u+\nss7KG8Qpvu7o7lEuEU3XRMqv3vSxVrNuikwM8qMekOT4Vy+eqtAcxqkSI09k\n/f9x1FP46mlHULTBbHdOHiIWEeSbZuKYOyQBRwHtwXLS0fGunIkag0cK6M5S\ntNFPcQ7FA2EbH+d9xl99CtJiFuqDEG+/84m3MhicVmvaB1N3SUv+TFNVnYSz\n1uaLLZ+QCzrFkmiOPq5SARia0rVN1WQDqe4oSQgTbZrmWxgYUHYoCxZycWFw\nLqzhUpEdQoXAr81jH2+wg4hK4hTyy1RThfuuxyS+1ygAfa+1rzQuH2h+8j4G\nMH3KRwpCqRkgpkRfs0ELbpxUsGc/RG8BkABN/Z4t9qyvuDzP/nUO5lSMQqVi\nruhdFUDU5Y6LJfFgA6lF2qsqVaVBs9Ss5IRqyBmn9Jafw68nUdlewpcj1tej\nvQmi\r\n=a/eb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCcOSUnDd7vqtmJqkHPX1MhhkmpROeEUfcPyECILC18ZAIgA3EIAdBUt6roGlY7sgeO0W0YTzecvhF3NQH3i6ueM0Q="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-e11fb95.0_1588580138349_0.8501685627242817"},"_hasShrinkwrap":false},"1.0.0-8b41eb4.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-8b41eb4.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"8b41eb4af6e6aead6be9b0b633848051d0109b78","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-8b41eb4.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-t1TIg5LDRTHCNPIBg15RCNOyLXZq29lpQ0me8YNaieuCyHZkc9Up691KvrQeGmdn33WDBDH2ZGhrznPmNP7Rug==","shasum":"5a88a9f5b1be60aa991116f2730da6a13569cf1f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-8b41eb4.0.tgz","fileCount":251,"unpackedSize":61206808,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesOfSCRA9TVsSAnZWagAAqqoQAIscR2NXTfjejFdqwZUl\njmu+Elf67dFW0f4hdYyGZd4wzfD0M1mJ/3P7ML10kiXtGOeq9Q/VSorN5SOG\nA4ZcHKVgosBGC11ACNQ0zO6kHq4olEC2WImSno0jG88a2kkX3n5BtMVt7w/G\n4b0nOR+XhejQ4LuUBF9UJc0u2SPFOcCiPTIRNvWL8Q6tKVAEFUozGPYLPSEr\nDEOeLxbs6yfTKy04JMWzs0RnNbzZRxY0uw5Cloko70C3t5HBo8DDDRt7EOn0\n480w9Lymmw/CQKpbMLXAhzUIkDj+jvPXS6svp0H1/YXobbe9m0lKn85NCJ6+\nk8SPsv/aqx0HVKLobIx3XPOX6VhElY9bimh6CJX/ykB9STP+dfWJ9VUjL9/F\nuDqecSu6jMjFD4LjznqVhW1R6PHUreizeT8Pd0sskgYQP1lJV5wjgvHVW0Me\nhpbb/t1txIsWfRSDFQ1szCmLL/hh77MRiie4CY/Ro2NHQdeXfDGk0+nGN9u/\nePlUU7OIeQVS2uojV2TKU8jLFT2l1g1bCsgRwum2tNYBNMpp+8dJAyJXumYi\nV3eL6SRoVPHZzUNfWqUqLxOaJ/yIUHuPvCUgCjpm3ZaSGDsuzZdktLzrdTQF\nmUlf81bWXRk9ei8Kv7PSibF5O71xMiDltic2G/0BP2Id8wUcZ1KejAV4vw3t\nCypi\r\n=8Frd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDjLQms7qp/BAoOueLWyZVFaBc5pOF9rasBbsNvLg328gIgYOofZrNQQ2QzjeK7n63ejifxKbAqSZpvoo9AWjP48sc="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-8b41eb4.0_1588651985519_0.5975572672414828"},"_hasShrinkwrap":false},"1.0.0-0a5d763.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-0a5d763.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"0a5d763fcd0f52a729df92844efdba708336d99d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-0a5d763.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-eksneemO5eemQEPCm4MKP8WWFQ8D0ntu2IJssZe3FdFZ0bSFVB66U7fHIhoAB/iTW7iFmTLlabz6bFP4rSnqmw==","shasum":"51c0c681f8280b22e9b9ae046f5ffcedd5c70e06","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-0a5d763.0.tgz","fileCount":251,"unpackedSize":61181502,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesP32CRA9TVsSAnZWagAAs1cQAID2zJBMTua66E28mX/C\nR4EIbulBeBg/Ovn7Xdx/VVNKIdVVcE/pBwPtYdBcBezNXHDqhhLSgWh9ssT4\nyk/ED07j6tBaOCOCtjROsIJ4PAUFUN/lAvu4Dho2OXNIyQyJfweD/W+h0Qnm\nElmQT4IV2bxGDjdKEsU0auWwpqEr9GsnQ5POW61HRLAud3HY92hmExNNoND/\nUt/jmtQdE96DPY4sQLVI6AFvLa74+FsueFBn52vAikrxCUMDCIXQk4w/t7hL\nB2rZWcJMt5obAs57WiQVrNcyY1GFkH1ORZ+dhBWNfHP4yu197Va6IFheiY3Q\nyh9ezcAC27CPoT4Ej7AWYPM59xcNVYgokABKqjgpTe9LD4obat7/ME7CkY6/\naHYZAmJCqogh0u/WZ7j7QngS4qPZRWZnBH98HwNsO1vc9FA35r3oqmpCrU0P\nIsO0/5pgVVT6AEtHb66wDGV6wrSAmQwe0gKuDFLL6fU9PoGuMCauVDWFsWtS\nKmBjrnIMjSWnylwlqjP7RrrJNpY2hWLwAE1dg+dL0AbwirkBl/DVIe2PoiAw\n5JMA63CC/vQOCIPEcJSAS8Ns7SHelO5pSm0lM+2M4fpLm+Og769fy9mHZhph\nW/pFjSnWmp6EcpcBefHYrCL4CquitduTdE9ikppCA6Pzqr5NX0ZAYYttwr5X\nrWqW\r\n=ORcU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBkXri5dg+OOpwdPCTNrdCFok7XG4aV+G4YCVV/xeZexAiAyY4lVMv6ZWMIH7HJmwNux8QLDDQ20x1dN3iclGEjHOQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-0a5d763.0_1588657653966_0.8824088811284121"},"_hasShrinkwrap":false},"1.0.0-beta.9":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.9","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"0a5d763fcd0f52a729df92844efdba708336d99d","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.9","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-uNz52qe8TzSrtuPCh4Cl5b5Pi67Q52lJ6ojmc/ReCG3Ut/17nLZ6WwSAMcpP3CDHfZgLfxLeE3qymtQjOx9AlA==","shasum":"3c6903a8334f1cb9d00a1b0439975afef1c4ab48","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.9.tgz","fileCount":251,"unpackedSize":61181499,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesQVqCRA9TVsSAnZWagAAi4gP/ix8FKoUXU56b6aBxtfQ\nSNts0vVAtv5fnsJptkZx1qtpa914w9/hJj4+Mep3MNY+iBeBNf6+zqRcB/P4\nKJCe2zJb9/zP2iGOMM9iLmWo5RcJxEH2+rF5MxNzHRO5ieC+YgCoPCFHTUZB\n75BsXQ10YYeuSwRfyjVkL+fKFkvwR/AEKDfZllU0bkShlqUnWN5I4qXZHETS\nI3Y3jj9bCc+ZlayMRXMj0IY6nRyvP3DQ5jCWttrLZY6sDkOm/HTQCIduvoK1\naqpFOVtYxYoy1OpkUKQHXqbo0VGr+pwf38VpgGF+f/DUC5sZPyNjyInYLCtd\nrNF3lXijU/+g8tbXHx9Zv8i0JwuK0gdTvypSToytQfB+E90Onp1IgvQ1K0Fw\n0gKUu/q6f4PWuuPea/E0NHUGElTF2w2OHg/V1VK1iEWbc+aZ7KeVAn/LCwOg\nr/fdZXZsKl+Y8cIUT2sAYmk98et0hrhM/8LD2uKSKsitwletWfDiI46f/kB+\nZt0rpUThI0DbtS93doClzHI+8b6Iq5Ks2Gj7E5Yr9I301UXtylRPdd530Tcn\n592EFgZp0SI+L+1OApOv5dNC7ipnQwxyyAE37yooo10UcMXj+zAsazieUdHl\noEpj/dZjtJ6q0C7nqd4/qtzh/XqRpkkZTqn4iSBbkk8zQZMqL4g0qKCsGLpL\nPppv\r\n=srBQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG+QD4K0KjpNcMdA+GFmD3u5nvNr19HLhtWsgc8mJIpJAiEA81U6sNku82lz1OjkV1leMHs2eXgwgi5GDilmT00NrYg="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.9_1588659561410_0.8415895821790822"},"_hasShrinkwrap":false},"1.0.0-6887515.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-6887515.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"688751583e9e8a30e298c50569ad9cd861150fa5","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-6887515.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-7Pt8DxaBaRbKP4ofjQ9i2SyJfwJ8MOZOtVpDOkHrIFEDs7CQKvNpx7CQF8+B6OsGk2LjLVyhA9KUuyPU0DepBw==","shasum":"ad37c402734d981c42b274ec3c89bc17df23a3d3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-6887515.0.tgz","fileCount":251,"unpackedSize":61185376,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetApKCRA9TVsSAnZWagAA448P/Rta20/JS9Zm83d162NM\ncOEr2rSuT6mNNqy2RnoyADIjU5krQmL61LXCMPeNx6e2gCSmWOi1pyXnqp0J\nSzmoa6SYbxSO6X3/XWxNkGdXrvm2z6py030/Fjb74ICYa45KcmuMftwXQOSx\ny5YHXGbukf+wBFrz1s4op0+Ddrygr1d1OnVluk5ZDTYymFBdYrM81+shJVPk\n8aQZayxYl010spnfoJ8afhh4TBZxSsrg1Uiq9IWIEys2iihYksZsIEYPkKDl\nH4UCp+vq4v2oF1SB+wXC6T+PnsNRbIwVlrnPyUBDGM+g+svcLqhFmgZ583u3\nyJI6fu751KD/USaIdyg8QmcboAnekiqnnUjZY8V2nGa3jyQMe4gFvuBxuZ9E\ndP6TJZV/EfoMN8ypfmJN4KKlCFZa2cz3Fpm46vSb6STeIWG5vY45bYmgk+9R\nzUSgaX4sKs9uPA5ONoL+/A8iFcJAz3kRDwK88wt2oHPxQ2pDnf6uP6TuUa4Q\ndw7o4CxatUxX0FT8w0wilaQDL5LmTlb2AK6BX9+TFAB6GTOgu9iXGQ7EaEXN\n1GoxDYk7YWJh1zyfzlq72m75AIlA2sMc8A6hlu2wIyWupb8YgvGVakau0xJH\nvkD41D2lPED5rNP1BBR+GSl8h+cobzbmNXaMxKkF6Bx6PfXY5ypihnhfVNvk\n9H4S\r\n=8nVF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDR/Xetz/XvoSzWJentGM+MXURVtE+LCKCIl6BuJnfJNgIgecxyjOTZ0wPNaTgotRQUn2y4qHfZH3nImkoToR5Z75k="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-6887515.0_1588857417441_0.0685625404751502"},"_hasShrinkwrap":false},"1.0.0-5a3b801.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-5a3b801.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"5a3b8015269d1086aa7b1f5207a5ee480db92914","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-5a3b801.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Z0fRrpzyKQQmaJoNvjMqlijtYOuWcwWnffTKis7xspYUKw+w1rnrcvnp/sM5/OcHFlpG268moTK/c3xOZEZTTA==","shasum":"8b5d0c3fec185ffcade7ca0eca007a4f78f8a4dc","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-5a3b801.0.tgz","fileCount":251,"unpackedSize":61183240,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetXMxCRA9TVsSAnZWagAANSsP/25eN28HSZlVpJWwTLkX\ngnkUlO/c4276UgJ8KDg2jFpVeoaPSfdFvPsu4Cx2SSJqCDbZEBEWNM8MRMwb\n9GJziFbDgv/bVUMs15tcyn5SOgEQU1vDNv+HZyH/PbfHYtiVJA1orpSLhn23\nbkQicYtNgEGhTcSIb/K7jeg8wsHxihYkqWFZ/TKT4l5U7fyqKHlFRvWHp5Iw\nUObkLuLV4N9sGXRGqqwtiNLJaD5ha+gh0HPKRq6klBGFUcjVdr6JdIesfXvM\nQwuFi3wGE5b9GAApj2CBJ9Cb7h0uJ+F6cs6+KumD1aPSchLIxGTAGgBoUQQq\nnGnw/v+4kVyfJHDtZcDtRH3flyTyuTBspbaH3yp2kZXyrx6CXWxt5LsmJVEy\nB7UuuyWKgJnbUfy3ze6fKb2y07i6tzWx1c+CCyNa8yYQMOkYfRkEsMSreas+\nNe4eTtGqgKJtpTenzZZuXNbHYe0NzDunE35QpnMT7D0QBMr7FS7yyxehCkfI\nNUdgxHtmczjClbkCbd5ckP6UAN0B+2XPc1CtcNgdrODRalqBq39tPvQmX3J0\n7B1q7iMUc3r5HyuykHF2G5kkP/e6cOqbQW4NB8QYLIQRvpKmnicWoDjkDIBA\nUJTECB8LVZNTE80F4mYpqeeHp1tK/jQ0J9oB0SAA76z+UZVKmawdJGAo8gCo\nSeuW\r\n=CqOr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDgflvnZLlTj1Nq2kJ+zCI9s2HhNEv6vM0am9S3LjCS+AiEAmqQ/WtWUBSpMJhlumZ9IQgBXD1u4Afsi9Pxuun7Aawo="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-5a3b801.0_1588949808363_0.06168732834758628"},"_hasShrinkwrap":false},"1.0.0-40d0325.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-40d0325.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"40d0325a1ef3d558f7a7a875bb9cdea69d663a0c","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-40d0325.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ecVfX05RHdONLS+fmPhdEf8+kM/QyVNEjlBfcut0SzY4XwmEVFLjnAe2vc5wzXuj6mEtzczJv0xq0N0tzxq+JQ==","shasum":"3bacaf2060860ec4e4445a6de6912fbf93398cf3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-40d0325.0.tgz","fileCount":267,"unpackedSize":61236833,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetYcpCRA9TVsSAnZWagAA0hUQAJ6zynYXQJEhI+R1/JBR\npiuktmeT9pJZYq7vEbZRARSF9lkQI0uCXXjfjreN139IgEFQQsOwYtyl93EQ\nXlVM8NAENLSRIRFrvawQUI821lu06nCnYfr0ttG9ja+BVo6wTs4D19wGvyRe\nIX6hdJobYPBDM674+iWqIvCmzkFvtg8+4vLfOqSbFWajMRMQifa3stsXYnQq\nf4geQQEn+lJUR4v9BapoU5+Zc47lYCGSYeJ0TmV/lyP3Lr3fnrPeT6oXOUdJ\nMdEvZNmHqtQvtqHSipMWAG15GrM7ktLLEUeYhrc2zrAcAi/MjfwKwdflaqoz\nQhkCecgVNB1T8oZuAlP3Cr+xOjn3E9kR5x95+GWwIb6JMsVGtJuXbYfBioCX\nni9YcgRmlmki3S9ztr2Yd874QPRHAwmCx4Xa3vetxdwCVwFqhNOqAdsJCWr0\nR8LxzFU9Ki1tEm37hI4igLC/FfCZ209CtNfdRIRV2751vA12tNjRP7ZG4GVr\nh96wBewiicb/IC2P9VbBUEsLq/crvsg7cENV1uFG+FLYXat3DFPuucGjOwxY\ny1Y4YGhTfh+LigJGTpX0gD2kgvuRsNC3o6586X8+/vKGjkwu7mD1CmBLY+Qk\nWRdAENWzKU/fGa6HbEqzEcqZognB2W7QGJ45vtzma2tV7lnhIwDKN4LNr4OQ\nVfKs\r\n=dCkG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICcu5xcdB38zOC8/rdgdFI/NZiZccOSPSWblrOGPC9oVAiBFYSJrvuj26j8TJTiBwyMp5u6zVbV/yJrYHm7XhhKV5Q=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-40d0325.0_1588954920830_0.6192792529657134"},"_hasShrinkwrap":false},"1.0.0-b4c3b34.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-b4c3b34.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"b4c3b3478997f05bd9b951f6e68c644c2521e858","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-b4c3b34.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-PRLsaCjROqsqrLih0M52kt9L6FsRrnItKA7NQyGiJkzOmU3HujfC8I7atKm1+EKLJGCHCAeSrr/I0MRpMyCueQ==","shasum":"9321065a75f4eb4e7fc029e6c10048f1dd9f398e","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-b4c3b34.0.tgz","fileCount":296,"unpackedSize":61684311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetiQ8CRA9TVsSAnZWagAA7OcP/3O1s2TYo/8feDGQFTtT\nsZBxJxeMKdrOM4KUNmWIkpPJhKVReTCzmnODL6qUisx6Uif9657Ylp14ieBg\nh7oD9X9RXbNFbv2NxN57KEVY6X0+oJp66/h/S6+Bh00sG9AHZxH13Q6PyWr6\n6k8MQ7OsJw4o0PbZ4p9m8RYqEKoQEUCnF1dRmg4PIKTEQU/e2hnKUeAmxcDa\nZhCNvcXqWJhRUdypNq9t0VFv4beEP/03GOi1B3hJRvDVZqthGmgbfdZpo5HL\n9ngpJ/AXq85HeAbferlbqw3DGScv584PgiOhF4MRbmd1n6qZuEkMG6l9+Cve\nLwcA2QXZfa9EgQ+V5AVptEUJ6++irojVMIzWjywVs5RieUsSuyX4X30+JELm\nxycQJzAj2mKzdsIJBBEDquTOD/b9467+w3dFwF5n3Ut2/cEfzs3ep/mYXRj+\nJvCwr3+8Jom/X/aU/9jskiYsvfPaNChb6dIKuy8EEKxGFSOQODkCGTg+/nUu\nqMdpKThMsRioVVNRUFXiFIruGvhH6sXKE5m2Lb2Jpbjnitn6u7/Fw/5uUTL5\nd8NGGfGVUZMbTApTT95YUp9MqqG2wogx9NY/LI2Yr6WwXkUodwUHSx/djby3\nygxjH/dkIaosyaj19LqQkxGt2ncofi9v91IfncphOpklDBJMS6H4K4xyBsPy\nUEiu\r\n=wqho\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFZn9IiFljvAmtbXU6lB3ph4haMXPc5DwBHpeJejCnd4AiB5M/hSGQBpRdUVh1p4QNs2Ta/+kwu2DKV8c8QH73/uNw=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-b4c3b34.0_1588995131503_0.98187557030521"},"_hasShrinkwrap":false},"1.0.0-3ddadac.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-3ddadac.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"3ddadacea959254604c95559109beba3bb85fef2","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-3ddadac.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-2ek6b4x7wOFFEdBynZa3ZpEtaKv69fdUb/oFssxoAwG36g3lAF1IgGlNEtu6wH/qyoVbtRFUfT3v58iOZbb/cg==","shasum":"adb957bfd77f190b5b5441474dba8b225a4d7008","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-3ddadac.0.tgz","fileCount":296,"unpackedSize":61684311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetiSzCRA9TVsSAnZWagAAUe8P/02iMq5iol3pnDGb+Vkj\nTuxMwv8okfVFhDgq9AocX4sG4MjZlcuXf6rR6zlw1FCPkVFQyrkNsw3cK8ai\nU0jbKfskV5dgsMQLzTdLGL+4Q8VjF65wlAuj2130WSRSlYK9bvuH6Yoso1Xd\nMAxVYgQf3MWNLhKD/M4aTXEMEEohaGsLirLfrdqrlVhAALW/Dxb7Wwt0Oy3f\nTsE5goBKjbwB9l48nWMOgcC/n8Vfk6q4bSnsf9umL1o4duguzenFi4VqlQrs\nA1BsbK1819KO70V7wj19WH/9C1xGLxAlrMzVRlTmeQ9Q/QJnyGGXCOrLcVXz\npvpBCELFRm0X6lrM9VfoVPq9xa4PSZw8xltkw+/2k7QdlgO32Ntmk42Mc+ak\n/fg6SJDFQSjObJ2V5YAhN/8PJdvUaVpDBD5AH+kPl4R7bQVrWWRonYjXKZYT\nmkgZvh6Je6VFKlYpaFuz7fbatZK1/k1z9MnntPcSaY9cO1f8Dwb4YDnVjrDD\nVr4mNPbdcbbell8d7tsJEt7Aqm+1rMzXREIq0yY2SaHD1Nv3X5Gnb47NLLVg\nGZhFMipWm3Nf1rVHBF0UxCPo/kdo4/mODmpryM1s7InE0yDPaNW/IffWCtYn\nYxat7L2ALElKCJceDi13/KnJB5Km2lV3ae8gIkTKE7uoQgsPiycRrH/D6Jrh\njQum\r\n=3Ug/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwNCMi3MnVeVPGmL5QG3jS+kji5Pz732SFFnJBjs8YBwIhAIyK+5UJmk9Yz21LlWRLkGozTY9qp53+nLAep1vu7FVM"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-3ddadac.0_1588995250999_0.9666417721237608"},"_hasShrinkwrap":false},"1.0.0-a334f5c.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-a334f5c.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"a334f5c76af438fecb567826f85ecdc965a4951f","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-a334f5c.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-WlTO6fb5SsK2TucLBmGxNNnZoba0IUEyRMRyQKCVtZp2SWyAo047ef5NEpZaJtNr+Lb27l+av31Prf24WwdUdA==","shasum":"57faa7f72f48dc0189b815f72d778b311a45f9b8","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-a334f5c.0.tgz","fileCount":297,"unpackedSize":61688602,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetki+CRA9TVsSAnZWagAA1dAP/1ckZ2c2ozr42e2TTwUR\nttH/aHpDLFgxMm2fRiya9Aht1HXmthBYMk7vQ5BGQYNa1hOPMuM+kkiZV8IT\nOssl7n/mm6oUjKxMjhf2C5hJFq8MBNeBBE2d3L8LzQT0lrt4yGK5FuP1RVdc\nd786ExKbOK4L3BwaLDTK0QBli3ydzTX5C0soniEE2N6cW1d+ptYsmjBeQwtc\nutJr2yK+vHrDRCiOcAHFSXa6lTCrUHzZ+eQSOrK/do7GhSf/qou+uB1zkh+n\nxNEgJ1+XsBPAPinrbOmz5/1EGwy+guwA1YQptZAuuZNbDqdsXmBOcMvWqtlr\n9BglaDFffjtWm3xljZO9FhV5RX4/HUzzhkqOvi41R3khkyPKBP/QySfYhexA\nVoW6vOPU+m4RGIQ5dE9krXkOE+nYT2EN3qq++H7Zu0Z63gx7nDHkrNGAoqcC\nWmJWlwo1Ok4AKZFc2ZB7u1ylZF33tN9OF6wx/pAAusyfyJKbeFu6g3jp25jD\nNZg3PMg9BYPUEQLnlTVBm7IFkSnDmfspxbGIxYbuDeiGcK7jAMzyfP7gKYmg\nlOlvF7Q7tTSnq9rVMUwlVDxXMEeZuj/mMSBytg4T1Ysx/m3RqaYXof/VlHGI\nVO2+UYizQlqV5h7qtMpeVzae0yIUajM7bx/4fPvzzXMexkhJa/KcmklPojOF\n2j5X\r\n=buSp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnZuawKXFwXw4fG9gI7Q42Gw4ZkYE0jmOFQgsYLj2zvQIhAMSGsl4Gz9ugzxGx3y1H0BVrL6qH+EhKtCSRhWpdb1Ok"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-a334f5c.0_1589004477772_0.9392945924512597"},"_hasShrinkwrap":false},"1.0.0-ab34c22.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-ab34c22.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"ab34c22d4b80064fb00d795338f5c69ddd229ca7","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-ab34c22.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-2mMJbHObC+5JmJ4qJw25vkPj6+UIe8dsEkpRNhXMUvAZx8hGaY+FJNiPSsX20vO4xzHnx7n284ZseJRmr2uSdA==","shasum":"d570bfb5483c5ca347cf0f9ff1c1098e8c2ef75f","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-ab34c22.0.tgz","fileCount":297,"unpackedSize":61688602,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetkjSCRA9TVsSAnZWagAAtroP+wXHc7VqrBDMvluaABxE\nci0oYH3fLKyQ6iB072cUUkvpf1olCt6NMKohzsEijXsQhUfp3ygC8jOtkZ2N\nCLEChxx2cQ3x8C0kPM03rNKt0xKq5+ODx1db06CKk9q1oe8hJNz9Gp5lNvvS\nzL8pDvvLEsxJpWhrIVoEM4v8oABCA9u7ozYDDZhVips5sE86padcOAOj68s9\nrNlr9wW2oxbIw9JYuGcwOAxSL8cncYGuAmLR4fovFZkA8pME4twHdo83uME/\nOuzgaFWcoEXEsDJhrEnZ1KD3dtDpRbQpT0da9i6f7Ngxk1H1w3CkrRpmo4VR\nDlzdubK8Kd2YycW+gWkuU9ckaUrRGLJ6H0xjDQ6H/NfSr/E7F6RBnYKXLVGe\nJzpLcoP2vJogkzuDnzXvCIpb8z4uNF3pw0TQ+iixv1aM/vBecSsBnYXMI9C0\n/2rv/BYcta7lLWmlI2iPKYY5frL4t5ZJepoKgsssuQxAQbfUDKdKF3UvcUBs\nFMv69NUKGeKVTakIZjNnBHOwdjDy5w/84mg5VLvxOUSIlwM9nzGz89uobmJG\nLYNoiX72ALB1rPkqB+e0wzaaVIFvxpCI8K5aOfmQQd0ygXoCj5+yG0yiwfeJ\nFa66/hE4mbVNypqgIqwZZnWVNT29d7bOrPSeHTLWLBCqDG2pSCzDelxSM8BD\n0bby\r\n=Qwnz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGf2rNCu8Dmm4x9zuH/Phy6yAb8rovBYFRPICViGhjBmAiBJKe+zxROYt5VkEBJ4tStk8n2kHKC6ZY7sX54PeGheHA=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-ab34c22.0_1589004497242_0.6686452538004339"},"_hasShrinkwrap":false},"1.0.0-7d39c92.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-7d39c92.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"7d39c92b14c75bb9ccd92d47251c1faf00b0f05f","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-7d39c92.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-/e9rEdQYgRpF8LahSp9sc7GFlUeQP0or6NjAfwHFj3Lju5dx/b1Gsq98H0/V/CJwWDjIEIn7X3cPox72+1+NBw==","shasum":"9a893bfff8ad40a01654f24e92d1ce9616096bef","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-7d39c92.0.tgz","fileCount":267,"unpackedSize":61236833,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeusL9CRA9TVsSAnZWagAAXz8P/0raKhaexG3eUVkVHntd\n32Mh6BPtAPdCUA6SNMo/FHE94Wywyqlw1Qxnb5f/QErGjP87cl8Zf5dCWb6/\nHRoA1qj9WTlPO/yoaLF4JC5K5kM1b+McD1E3MMWll7qze+aMYRUcVLyGFZpv\nf9PjNoxrvVgWMm/QYpvMiPLDgJTnBHyzvb/4PE8K11qm2cvbKLkcfso7vqhK\nkr82ykmj5+Su6c0WnGKPMWU9wg2QDR5FExoEBezfl5lqHN/PP2p8IgsD1AqC\nwZJfZRvKnTNm7M/+1e9b9NyVCOwjc6Y+e2GKDWpvh79gPycl2fzk0k24oqLu\nuHWZ5wdD5hIfvvxcuvR335TtoIuSumLjGzqiBBYdwzA2NfHGJI91tHGvx/aN\nD+PfpJJasRfWlGnxnAlF6c1r04x0QBeYESYNSR8dfPc8o7fs8xR5sLnIAOya\nCMCbB6ueiGc9wwrh6013HLSvemu1iJpIk48vvsE+EJsOW/ay05FWoqrKosfo\nGyX5PbQ/vrwDi5zQgX3endEe/xaMlu1GngLGeMmgvkBOcMp0uqiRBzzDk7IU\nYgWQutXZ9Reerxosk0xXgcS5f8VC3rnQ0ogVIkM3d/lVbmvKGPx1JuNenFSL\nmtiyT0Uwnkqs8PBeDrSHw8w2MesIw9193h/YuVhOpwJQhc8qKc0WH9VsktCJ\nvRTC\r\n=Qik9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIArUhR27S2n7slYO7F2WhfGGib0Cz7jBsy63fIfR6UPJAiEA6rJRccWGlhq5GkqUi9hKIdbPkvwEFxzdMrb+ftXW5pI="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-7d39c92.0_1589297916113_0.9056042822170591"},"_hasShrinkwrap":false},"1.0.0-62b898f.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-62b898f.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"62b898f3205c4bf8864db8d3a45b0c88ab16badb","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-62b898f.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-RyQXXeghJJope838QvDaW2cciGrUmpwi6DUUUCkbjVGPCf1DCTRYEL0eCje/UehegDyTJkQrzXlU8gZKnSCsyQ==","shasum":"7c24ef08bf94d7fe887d9a07e2e5478c73d4a4c4","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-62b898f.0.tgz","fileCount":267,"unpackedSize":61236833,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeusNQCRA9TVsSAnZWagAACBcP/i4SIeOu0Ig29vlOmQsI\nuGM4qBLk3VZqlsSjyI5AdiyFAVrcWNqoQbTT6GwZTA8E7eu9blyVeAMQuODq\nJoa98DtGBpENBZ2Iq1cvb+bVT5JTlqJfv+5IsKXQzcBPQoGUM3dxxmCcc5OD\n4/ipizlMnRg5+r1Xv7tSxFcsHDfUAjR3A+72OwV6Q9clekiuWTHeLTxhYoWl\nRsUko1ELgZFtgD57vAOWCB5z0rAIDWnHpYw5CaZwvN5rpctxUvLrxrQybYxC\nZD74Fj3RgZ76/4GpdyhwwDsKJqnX7s9pbS8yMZ+mfyOEKePDn93XKIl62GEa\nNOrPU0He5ql4e8cHNYLZ4YxsViiPMwDs9gPEzuVIRX8yznyV3HJRuqNCTcD9\nwfIw0mSp2glRuuwm4FxHvV81dsUHEoX1Yp8KESIo5+EOY4zX98VMPt3Y3OV1\nqM/ijMPlr7fWumnd0vL91wyMrsCydBY4pklr4heZOQAGoFHqRoSlnbGrBOSt\n22lO1STf7WRSz6bzq86hgAK4MX4l20BmAeaOngULmGRmy8DcGGMIwIGsx2Xc\nIAaXbNRpz9NCIjjFYWJM5/Auw1zATVrsVjW0Ai/hsaN8dXf7srnZ4pyt6gPp\nkM2+yj8oKxK5/1ysZi9rBKvrx2zOJAWOV8Kltdr54izL+onxSNtB01tVhDHr\nU4gU\r\n=O8zA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCd9Bxhh4W3GJbFeDfnVoZagksWkvVkNoFzPgMtokjZLAIgcvGcE5lOTWImiBpZT1S1eCEuS/2k3mevL5lWbN2THpY="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-62b898f.0_1589297999338_0.9527343849270018"},"_hasShrinkwrap":false},"1.0.0-098168b.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-098168b.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"098168bb608dfce35f94e8211b6c448dafc5d8aa","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-098168b.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-x/0U0G0Vk8Aan4LOtkPRppYpoOOfEWq6foMC/facpt+3Nu1Ncic5lHOqJ2Zo46/Cssxn8nJ7fg3etjsjDkyA3w==","shasum":"a670e7bf1046648f9680237d2a960ed1c67c36d5","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-098168b.0.tgz","fileCount":267,"unpackedSize":61236065,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu0pwCRA9TVsSAnZWagAAVrsP/0715QmTwZGo8vNG/5/L\nfyGgWnvPY4TMdBFeRm2ytdZMxSxWnOyFJm3Qa2XQkx6klhxGCREGAVvSQZuY\nJVebfapq0jNAfF7e0qD2pIKQHImUoOz7XkffRVxSA/NofB1hOrgsYg8n2gd5\n5gYX405hEbuoMYP9AEcDhZH7fHlaYAXmX5piakXGDw8cFYaiJDakdF3fotfd\ncjwzTdTHl8OAqk2L+s0tQUR6fMfS7ARFV9SjoSP39jg53MCt3y2GSQJYCd2x\n1R6c95IPTxMfwa4Qio6+xksKVfvQCuejUhT9qkpeXOB7Bdqnhuw3zSYlGomw\nXNyjF3kB4YoPJocFzvaETVwtRw+yc5Xp5zv4vpXQYnkOmgYSP5uxaQh1lgHY\nJGWS+aNbVgRk+WSkp3oZFhub7jPL+BWLlBa6j6rj/ndoHuia7eZXJzocXzDB\nLZJWHNf9FLWQk+cFe2hiOS5Vebt7XbT1+Sm0SS5UAydBB3XXTzyOESEcqQi2\nwb7UmayksQDO8klZ71Rv4HjVGZesGWF5DnjBkmiguRNR2RoOuWu1PN/CljPV\nEvz/ZhJ/ajw0ag5o3D4MtLKcQo+PTzVUFeI5HH9jz4HLQOU0MMr+yWUTjtYI\ntKqhZGDY90q0dqTMskk3bYEhxMs1uJ6FQB1Zl+oV53Ywm/sl2w+RljxLsMii\n56ZR\r\n=si3L\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHGqMI4UScp3LnKXmyD4dK8Tord4IsVYmAbJWqjt4xOkAiAT2Ld2Dnd5q/qrx6anWq0Mc/xLqQaq3L8K1nRcgXziZQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-098168b.0_1589332591779_0.07439208754088256"},"_hasShrinkwrap":false},"1.0.0-b74ef03.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-b74ef03.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"b74ef03a4d74125ee0c644c28e7cd7adf5531eaf","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-b74ef03.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-zp/oowXwHsYAG1JfnFQPDDJAuRIc7xirpJWorsKQhjzo91UIkmFGEbSzFi8/P3QVzzaLmqyLREvDNg1sGicPxA==","shasum":"1a1f28c5af3b5c58e1a73245a30654d37bf0d2b4","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-b74ef03.0.tgz","fileCount":267,"unpackedSize":61236833,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu1C9CRA9TVsSAnZWagAAco8P/2pCZXfdCb1KebFqXCIS\npNAzkpk2vwRYwMa6oIJY4s5Oc3rSqPAaGam9ooMZm94IPUs6B8r2qvSZVIYf\nN8tFhEsSA4pfDk9StysHBqVvrtPgfdmaKAZrE1DJhpAISAgL/8LHwRKhZChg\nihzs7FMA86nYCSrQeOR22NJFEfygcMJJ4Gq+oB/iunj0NJrTvGnC5DYfOD8O\n0qdsW+mTtGxbW1rJyp4vwrNGQoAzKK3jBciOW+Zz8DhQQWuvMTbDKcaqDw5O\nSuseDyNflwWuwxnbGC/O+HF+Q/WpaULYMO4kVSHWx5EHtXHLQZxgu/pKscR/\nIh8bUC43ibHfTBJSCDrMLPhhPlcX/Leqq6rqwQqapGFXd2d2YuP/N5mgF1x0\n3fy9cPuHZTFRiZ4qHVY4PBGtZkuCu59Nxjp8eks4FOpzsIo1069UFpraAdAc\nCqisoI+FXaLeE1+r2kOqrB+0RMl3kmX3D+LRxxGBW+/oRGfG5sWrAMP/vLB/\nJJf1YsGW5MAZFWUITRclvZxb/xXw3cPrgJpaWMCDITKlZPOuzujyv82lXsvV\nFHSnTp89Z8z/k3DFV87gUkfhfGVctTKkjvDEyZsuurMq2x6o4E8+7jG+2wNN\nnT+7DTMgF3Wop7sqHj2tonsmUvy58C8e7rW3TeqghKY7l9V7ItNZSBSqHwYN\nnuCN\r\n=0BuR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAJFp9braxSHnuFo+y/YE15ywuCEi60IGN2k62ro2i+iAiEAxOSwHorB1CJtxtf+fafTkrPFA3clJY5DT20z6GGpT1E="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-b74ef03.0_1589334204355_0.38670580662228593"},"_hasShrinkwrap":false},"1.0.0-da905d9.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-da905d9.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"da905d9c7f027fec5e1c9483322e8f55ac8c9777","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-da905d9.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-l9dXagFpQfPPssFWxsu5oBgKZ4IOoSr8dOsHUrk/UNAz3VtCRcWCuEzeWyn+O9roexNbzpnUUZPsvDvM5QS2Fg==","shasum":"7a4c9f6d062a36674dc6c4853dbab891ef6fe8b3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-da905d9.0.tgz","fileCount":267,"unpackedSize":61236065,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu1FWCRA9TVsSAnZWagAAFS4P/jHSQKqoLhncumvdv2CT\nNJFYwZeHsEqde2MyNlt2Q8bTGX35Pj3Wml5TqsYNwF2e9oyEy6M5oPd+MY7Z\ntQ6B40XSRHy2V0BV0LphaVcXriKcqzEn0Mscu2+I/485Qz0HAVii3IeNuIbb\nxFSbDbOa1onKJ/Z0EZk7kR4qpRPZvju8E+wbSM5kIAmwIKzcBFPVGZW9L+UG\nXrLj6+37avOJXA8tqo3UqzCe6nCfRpSiJhTk9cPp4QuOUnMH8velWERwpBZa\ne1HjqoO0iQzMnDRchYp6WYl/82ShmXCZXXCFVYIIJxa/ZHpfa2tUDL7D4WR0\nGKMhGn2TxjjHFFPdnH+uoZeleULXqww0i4rT2wm4HbZn2nHJ4dviyox8vQ1E\nLMoug3VvENTT+hxQ4Ik/vrodCmGv7p3azss4xtu5OfCyBg6iLq+wyStBcLhO\nPLld0LusCw3JZ8FDCAsOGxIEun5ZpVpfCXrgrLeq5JdmzLk26qkwA4HfWcMs\n4AieX9Y5XLjbyM5Tm7Hu0l8dqHeBOlEbCwJ5eq6nDYmbX37q9EZzY90vcTuB\np1HRNQanCMFpyfbD6rdmBkFEhxrFSi6dkgWhYmmPcAojZuJjvgztUehsATzz\nKNpjeeGRXQNjhH2FZqKHPrdO7wshbF97EohK+KEjwq1J68EKOjh/zCBvFVLi\n6mXn\r\n=K0I7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGLZ8zaAqrsmaIr5KYmGCRKohAsCxMyh6KNBvpEzyY7yAiBU8PMFw8k9CnrlNR0zIuB5Nh36apQq8/wypGlTQaonYw=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-da905d9.0_1589334356753_0.20409892656244732"},"_hasShrinkwrap":false},"1.0.0-eaace91.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-eaace91.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"eaace916c56dd276d3d64e9b962b13d884de5c27","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-eaace91.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-OY7Eu+4TVy1pPoMw2f5STDFB7SLYPKD6rN/CRu3/D+f6Pv7aopryNTGcJylj/AWevD9XKiZpSNUQxM08bnZgcw==","shasum":"093c2ad3a48ab6182cb93c8317bd3b7f9a68783b","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-eaace91.0.tgz","fileCount":277,"unpackedSize":62172805,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu1OBCRA9TVsSAnZWagAAvtkP/1IjEijiKC9UR7HR8I9u\ngcQs3HjqxdEO923PMpLef3Z9BiHss/LDMpCJro4qfQ0AepMkHCd4U4kANwKP\nga88Pq1QFzRdHqDW8QUprWTA1CnIzJazJJAJoouX2sn6oUnLkp5mxKm6kVys\npoOe+M0O9wxdIWFT9r5WWaHCTvv5MWtcDUgNQ8OkUzA+7Wj5Qs75m5kK4OmT\nSJuP/mzqWoIWAMgDxuWglYmHlMtq9maDSACGF13JIVluvNXVQSR3wr682KwP\n3uiawIuNC+ipS6wS8XpgKonX18KuG7KflQjsURcyaRPMonOVlXd2biJTfjcT\nuyMUiVE9SRZN5GTBZDrHG4pOQRmPGmYM1lnOnlFx8eBk+9yfcdoXj9O9XyAy\nmTbbJNzWtRkXRMAMvNusoKbPtt0Sf2w4e+DmXRAAVJo05iEMWR+zLXvZEunE\nXKrTG56f0oahi8y5oPDNaFNZLZA23W+5/pubrf2wUXTtKXaIvhHmGx2S+0D5\nPPYlHrng401yf+KKjgToyld76fC00znrEVClMtqanOubfSSnIFGXchoHxMQ4\nnDh2fOy+6fZGsqOuMa1QtWrp2asJbxPvTbqOijRSmfkYn7g6d7BAgtuFGog5\nMOR74/I5v5w1cUELTfDdK0bew1bXtxwRVnfzM3rHlWGvo4WXsjhJPUs6OhqA\n3CsB\r\n=BrRK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVei9xVVB9XZ+macBP+N0CmRK8FVxUaoTYfRJSEC5sAwIhAO2mBp0orLtFlcH4XMGfDTtvKJk8Q2NwzNVvZ8g8sZJ+"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-eaace91.0_1589334912650_0.9744592600043316"},"_hasShrinkwrap":false},"1.0.0-3e84330.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-3e84330.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"3e843307c9ae1e973ac7db7d5010c3ef01ae444b","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-3e84330.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-lMMghnYDcxf3kxmOi2Q6irs+6IqLB0neyWMgHchgIHEx6xwiIs+RE9CBWnRlNwUBZi7FHOoaEuqrBzOtZSU14w==","shasum":"b5d4065703b81d8c3238a5da98e150c8ec7e3189","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-3e84330.0.tgz","fileCount":277,"unpackedSize":61443696,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu1OxCRA9TVsSAnZWagAA1poP/02afdbjg18EtPd3gNro\nLGzOgZVaYQtlUEMvz4Wve8AxG0zvYpmvSqmmYjSM3hXXF55Xvor5WCwn5tjT\nNOs1Fvv2dOVsNzHBgOXYQCvOyiiO9tj/G1PzOUlb1JucwEe68sUr2FmavOTv\n8t/ssI7n43Pbrm3vfbaVx78uvgry19rE9F+3YG7mKXvMfhWBOjTjGXJvPOkI\ndcgGPl7C65ZsQM9SXddU5vtd9a8t+/QFBTsQrRNQ1qINL7wpyI4ERuVax5fv\noo06MTzosGLZUFUaAIM1InBWKAsPTEq0IPHNNf2jl3VWgz1AnCNQenRnjBHM\ntZgr/thLiWfGHwAIdWiAvas2UuXquBgdUZT8LIgyZFtwYAAz+JW0LiEW/beO\nP/MOEc/u968M/jyrUz0DtQkiNrJ8mCT4lQF1yl1aMVGjOTYfYB+V9RpOUVL5\nOE2jlZCwRb8+YW30P/WkNlj1iiUwtlodqUB+w5ys6VFkgJTK1u0WY2DxU2A4\ns5wCb0kRZxQ1pBOfPgC8vyIMpHbmEgifEnvL0X4nt84PFDzbTBTtKZPnOrUU\n+CWgYZRkR2BBm6DGpCvLC2mWnb/1VmTovPHf7SVe9+aa41DUf58Q7YhA7QL1\nf0cPmTLxVxnESNhKDHBMtUzV+/A0UALhzu94iUvJZNTTL7JWCC3uDz7ntBp8\nQQvV\r\n=jlkJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAoWwTHZnLqMtR8eLLYZfb3CSJe1vfagAVUzmNiFrLNAIgX6FSyaz/xwLrisKeCtsnyIX1z7hk/tCshViCFTODgZQ="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-3e84330.0_1589334961106_0.7129380644256134"},"_hasShrinkwrap":false},"1.0.0-fc249bf.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-fc249bf.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"fc249bf83a4d3fb0b468ad5ea3488b45ce0890c7","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-fc249bf.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-48lLZddL0bGGRrpcPwOGF8l4zBcFLnulYlwynTncifSKPs3ChtEmedQ095bZbsSWFYf3yqn6RMnipBwfNOBX/g==","shasum":"5b14301de25e7b7003de71751f4306fbbfd22af5","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-fc249bf.0.tgz","fileCount":277,"unpackedSize":62172639,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu1RmCRA9TVsSAnZWagAA+XsP/0qQLR4AyOkwu0xlzELY\npDljd6ZGsO6zZ9i50UMw6TvEWyq6dBDitHT9uTLPFR0OPKJ3OUlBz7aioO7A\ncyuhyQEOdhfTBCMfOfXI8YymWsNTLon2O2UjN93AOzcXiXUU53RVkFEhxGRD\n/yXrJFEerqT5V2xXg74s/k41Kvzif78wOzl0YAYrjfElg88SsreFtktEzOGv\neA0hYqLups19DSekGk9/KLMXR8Ws6UjUu5p1URxpCjmpGRfCAqxHcWJsr2Zl\nKaVvA+ClScAMHWQaWvkurY9EUpPNBQmIa3pVHcTMa8xCUrg/SvRVh6XSMSLO\nRTQCkJRCt/QvgnH/1txoPDAySR1x3iNVudJz3DNejfbqDmPAn10vJPxFJvls\n12EodUfXSXTAXD8Gjuk8exqKN7K8IZFLDb1nSigl+WkzAzTlgcG6J+KDmBRI\ndPX822Y9602+slzHBM3zbLZVm7jNlCoFESv8dsMeoylbAnylTYIFT1us+Cok\nB0NQ21GZBGMouI465M27kQH8DWNat8thqTqs2+iUqzYn9UT5//5qwZB0v/Tr\n9pSOhC34PDXrcto1TYCeJOAzRH9VSfntYnySAgXh0FfSpZed2yxHi2+tRnDJ\n3amXBGsLjlFXOEDGLaSfDuKTl5OpV5J2yucUtHhD03B0Ew7srjfM1MAIft0J\npzT/\r\n=Yb4q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE3gx8gfRLSo7H3BPDciUbD6Hu3to8Eur1XMFtmKRK6pAiEAmrGL/P/bkqkO4GThO/oMgxl30u116ujB7rHdi9FKtAA="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-fc249bf.0_1589335141336_0.2865645115879585"},"_hasShrinkwrap":false},"1.0.0-5778171.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-5778171.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"5778171128d9eb57bb2aa3953b0167eeabe3260b","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-5778171.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-d8lbjYjSSCHhlJfG5D4gd/VgPjVLyM/bZr4+802EVyGi29wYMYSYmYclEsh/lVQThhJ5JPSdY0UH7iKbjgpkTA==","shasum":"47018a602533f230aa9b91d4693e58817c70f4bf","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-5778171.0.tgz","fileCount":367,"unpackedSize":62765300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevjA9CRA9TVsSAnZWagAAdfIP/0PW7dc7qGEwHhys8gTU\nfo0Eyhaz0fS2ofqPAduBu9tg32484FSNwCYvJ1idlT1BYOsvC5AV7zffW+HW\nmU6N4OQbVW77o5zTZg0thdfi2nBYyehq+umgBUpv4JQUvgq6OzsLsf2LfE+F\nArIHn623y82oYQAEtwxFvYZowc6BUkfmazFg6er96eTnh+sGDXsKbvpLcyx5\n6j920CCxtrPlJsut0vW69v93YROcH87nX65EhlfFh/1ZwUX4wi5NDUHkImcY\n6mE4FXG0wq6sJvwNItrVBTuogUzXo5OohESEBrFeZG0b4LVrbQt1/cm2y0aW\nub73O/W0CIn8DQ7o0YwTbdnS1ALy5O2EAtBedvI+/nW70NwYfTIhiuzDGabk\nrA55jbKXnngdsRxvENDSgdJ85maQYy+MEl4PyU9dyNAlBJyHMKS7HsKrZcfY\nV0zFbuylEsoFBtZtNf5sBR9AxSSRZeno/RgjvUkTwRkYcTi1xQprGq+2hBrt\nsx4mmjUL1QbbASjwd6Cy7yNVFjV41IssNMbGWHWt1K2LGmt2Tt2tS1LnCSvc\nFzoLbvGo/9y+HqPs1Us6QRVRK+g+aLTsbR5AZdqhghIYeUoVTuYNlnhA2JtO\nAnIx1gkJjuEdf5FEQPHk7EGaNTcAPOIBqdFX5KHMWSNs+5nFHnbG5jllHnAx\nUg4I\r\n=TqLS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZBpH5KX9S1WCXqZYIGsh4XPR9R/3PZClBTL1C/s2oWgIgLd1cjLs+RrsD3SD/yWg9nfyI0Rd8ACIj7koeZJu3H9U="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-5778171.0_1589522492583_0.7322663062011656"},"_hasShrinkwrap":false},"1.0.0-b38e715.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-b38e715.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"b38e7159b185c5162befd92e403dd1563221d252","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-b38e715.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-NqlZrqRv1AYB08cSYSpGw4iGVjXqBgDOj91cRkWl6rCIGgqfR8hltwFIb6l+0Sb2Vtk4b3qLpsY8oR4kmqtW2A==","shasum":"9760f94844aa8feefeb7c8192a96bb51e2657145","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-b38e715.0.tgz","fileCount":367,"unpackedSize":62702743,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevjN9CRA9TVsSAnZWagAAkh0P/RFZPycjwmeIZ1HQBWUw\nLOB4lFU2Lc8eIvS2G+bSdeid3+O9FOSf1IdaYKOgOjCcCm/8qao30A2sZf1O\nOB5vX25eIWPhIDrTxccerEEm2y5lXVbaEwPqEExS6Uss2FDoHzNefrf7PZDC\n3dP9Ty25CZ4iXo/zNHVnVCEj6eepMGYfDybAeYBVsi2euk97mzzJbPxYVtWp\nuuCwVFJaIzjP6BuFIpFFbMsy30FaoLRkHH2GnXPVSkNfLB3MbInX7su42ooL\nEWVdPR157nGyzR8IkUTA9Rqt2KEKYHzqqUWYNvXNEzKWS5GtLyfxHsLKU41s\njzxY+ol2Dax7vPubGUJTfeiWzduEOqZhCljM+cQlhPYVtlfHWuQUTUilYEPY\nAoafH3r+EQddyidfp07caE1VeI0igWx6FSS0IDUGokEWdMimLuaiF6Q5tnIa\ndcg7n49ow6Sl4vp8wduRqYg1zeFRlalvFoDCgFE+3PAcnS+jzSBx1Ajie5PT\noSM4STcAuVsJTJsxq1xJh+WQHCITbR6pxkzTlZfaLaCms4TBkPlLVlDAO/AT\nqvRk1rjXESuq6H6hc+/lS1VslzWAD0rRXD0m06kzwE/MVZ5ek98O7/pusZOV\nxDCuAD2OzLAYcqZog0R8u9kjv7Xe6kXDKrNCE4Yy4ArKi9xnU2WSqsUwAJCS\nFAAw\r\n=yVpS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCgfWFl8LwR+XC31RutmF135EzFlRRRPH6Ovxqa4GylTAIhANUrIG6KDYDah21EVEwkTkH8X/MJFM6IZNIB9z2jXwqN"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-b38e715.0_1589523324251_0.24796519327372635"},"_hasShrinkwrap":false},"1.0.0-87a8cd0.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-87a8cd0.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"87a8cd0dca2977eccc93908a93471f4e08848cfc","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-87a8cd0.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-lx2CU5cdASiTxXqSRELq9yR7NL0A6NETvcyeADnUPlSj62cTQpyii3jmwvuAnMG1fBIxX860cukK6F4OTC/L8A==","shasum":"7e517a88ef7011f654e99cfa9b1abb5a5eedca58","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-87a8cd0.0.tgz","fileCount":367,"unpackedSize":62765300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevjRPCRA9TVsSAnZWagAAY2YP/Arc5J+7A5Al4TM8R/oV\nwggJlV4KrdsmZENxZh1LbxIVZeM/fI4Nm67JYf9CbQj5pJ1VykLeiZS5l0jq\nLzF9kvcqksYCdoz3ZvbZqCO6ec8Gdu0rItyPku6WJpbky4ylJYQ/ewpcUMOA\nU6KihvR9AB6ajbinux2XSRi3h/KAuvXvWp58rHVdpmHgBwOptkjfvw9eluXx\n4NFA7ia4Q1HPGq8glROhI19b+YHi4rJy6YwJbn3z6ed1XydQs+a9yz85gTDL\nrI/s5tmm6VpVelBdMnYcsZJnQLSdh/WI2i+gSr+E6vVj2nYlWccxdFwUJ5tM\nb5EkjcQqx9JW3DZsk3OCZTSY0QGzNHq+ngbtPkBB1rNHJhWbEToilN/PmlIw\n6C2etnzEdG+HE+z/ow2649xA2dfDxQqfMUg/V3R8CKNyEjWQh61vYfILwYE1\nK9Vgq5JLUpfUWKun1Q6e4KUqzgPsEBcbKPTMcyvN/jFHE6NnJJ72VLPnr8j7\nmZ81qYo0eOlfJukvhode2DIuR8lZzqcRpo3PxY7b3/oa5coWd5QIhmSygfOP\ndS6K/RETl5a85MkZ0c86FBloCp1GG8mO4oGTESpm0xjN1ttda/aEKYlDDeM4\niXS3l0l8dQoLQjmZ2hZE9LE2xNFgVNGVHV2zJ1i1b5T+99vrsm2yvwq1kOzt\n5XX8\r\n=kEbU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID3WbkJwBWFPmAa09xGu/PTWhptsWd+kPVLb8S54GX7IAiBkoEwpluqXu6iRF1GsQFfwkLRukHPkESUyPgP0VEksXQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-87a8cd0.0_1589523534337_0.03838082003797694"},"_hasShrinkwrap":false},"1.0.0-be935fe.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-be935fe.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"be935fea2c3d192ab1a9133f2bcc180871bdc9aa","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-be935fe.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-KncdMMYA8bXFkSQpvfpwdbVe7MZwMPfWU4pSWBrl0q3yk+NT9tclZloLR8ouYc1fJBJbmjKqLVfI+oCN10VnyQ==","shasum":"33e05930d6b4cb6eaed8c031677b853bd5312e35","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-be935fe.0.tgz","fileCount":367,"unpackedSize":62765300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevjTFCRA9TVsSAnZWagAAfy0QAKBMEYYpsN7syAKkZHOI\n4aYYCvgziWyNpjMAs03PtFa4uBnmbTxpiSXMAr3YB76vpVz6RttW/AEGLWY8\nL89jtoomgaMqBpbB3mQY2xoBO+lYhM9osco4hIMCzkwHa48iKYO/I4bLjiEg\nVJQlthHQ14txJL7UazDJifLiSRqz70t2NzTOdjRnbhLQdW7d2r7uJSfuUfMf\nYoojshs4Ue2qr6F9euZhbNziHg8XYf3JdZtaDa7B5yRkeBK0I1lnB66npEhf\n0/77jvNY/ZTqltvPjOaWxsqcDIxg7g7BwYNR4txszEK+xI8Dzr/cXEa8HroP\nkjaJFHMKUHgM2RibtHYv9U3kjNTpASuZA6PWPaaEJT9Hn4qoU2S3G/S/ZEfa\n+9oqp2lNv5a1KnUAKSAZx+Wr9FAPhWzn+xqU3KjaaT5AvXzv9vJYoA7Y7cZ1\n//UzYy98J3sVtt8AV9VUskFanQQeE+thKKZVSLs35nO3n0mb6tx9OEeMyLW9\nUaPK/YVhrZTl8blaQObF0Y1W3Mq3aakmKXQAfiHVn8jrj5jpXQWtifnwjQZa\ngr34tZcv8oRJUf78R/Kjzl9eg6XraUILF+6vaxo1AzAof+s3bsR0VC8/QL2U\nLZDBPzkKqnkWJY4kR8CuLod/BxR9LQ8L/KVWpxLgKT1/0OVf77NGYM6EXXfY\nJx/E\r\n=3OA2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDPqElPiKDbO9P8JkWiY92bVCcmX+K40fqAFW5DmiB3HgIhAPscPXp7n6D0Z9UZovLeBEf6OuRf8Q2uuxFSOyP+MuIB"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-be935fe.0_1589523653001_0.24615905656578807"},"_hasShrinkwrap":false},"1.0.0-60f3105.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-60f3105.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"60f310549df214a4a37a854ba904e5bbbd33b3e4","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-60f3105.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-FrvIz/PBXeBKtTlzqkCsvYahxq8mBk02ejPCZvYtd+mZOP3yhOn3iNFaV9/vGXwLLucy+iiKiAQ2MV+jXtZ4nw==","shasum":"adf4b239134a4cc1e3a24997870709015077f56a","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-60f3105.0.tgz","fileCount":367,"unpackedSize":62702743,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevjhnCRA9TVsSAnZWagAAIWMP/jBweCf4st7sYjFKQsP+\nnRwNeI2ZrVR19ugkYaaVa3XbjJyspNZQ8YMmRPL3iAFTvSsbEcpS2fXHSQhE\n6qWAPFlS9b4h+Q9CQV3krgiuBVFZch6dfDepXBiEIY/c7gvVUXURO2a0xWet\ngiwhEWwSheuukrMz5MxAkAa31q+ZpPHMmsM/vY9OS73q3RY6iM8tKHomYPsl\ntvnyuNgolBJ5sOH+RO1aC/1OQnrgVOJPuH3X6w1zCppUw/OZyAK8Y7TNMXUg\n5vpBW5k3XaQuRHy1RV7eqbODI2Iu4QIb9HdM2Wfhtuva+5lZVgiz9Xt9+WQv\ni0hxGt5U7PhfRrNT3BLPHL14FjjVvDlFZ6AjqIjZkii9AWcYu9GOIAcp59Pa\nobEKZToL3h+oPIsv3vYkw4xsmcXVThhed0IS+Aj5dWMp95CeqK3+wPQdAYdB\nUb+A22KcmA5vAo3gpsMT/HqgrM8+V+MsRP0edeCZl2wm75+R5dce+9hjzP6H\nM93oXHRn6t+PUaex2LDBbfOElZc+tq+CS7brenQ5V/Go8tqoAkI3kn7rp0Ji\ncvNyAQk4zYYXe0tcTH0CyUYXPNvUb7F2wZXLYzZPQuacZPyUCNbUz8899pXD\nZhqjcxm0NEJvmUY5bcqV+ZZm9/n0FG+Ie5r8rWDrFOfLOPFJVbAoIfmCMt7y\nSu4O\r\n=/Dno\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICIXXvyPFt5/DwzkPTaVOEzqKOk7MZ2O8s29udqe2q49AiEA26gsAEvTBaXOa5sZrXaYXmRITfy3cc9KwAlGrq6W1jo="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-60f3105.0_1589524582371_0.9482881558003187"},"_hasShrinkwrap":false},"1.0.0-cc4aba6.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-cc4aba6.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"cc4aba6067dbe5b4e16ebdc78866187b42479de3","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-cc4aba6.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-jEzuBDsyE0xDQjny9n7ERtUIIQzJY6WypVnPL5QyFRc33aeF1uESIs5XBFXEvnci9iHGAw/38/6Rne7K6CHbBg==","shasum":"0bd37eb541f892c4b88ef9b82b00b9cdb4894aa3","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-cc4aba6.0.tgz","fileCount":367,"unpackedSize":62716697,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevmhDCRA9TVsSAnZWagAArxIP/0fFrLHRBQqjrPLXnyHr\nY58MyPnt4jF6qFlKGVTh3jglhR0/opACLuM9qCZvndfhahix5qYrh8BRVhCc\nqu6ek5SXDk6IRm09KhSVfB8BW5NGd/tusaMwI7tYP69hIRrqMPjUqCrPGcXg\niyczSm4oaQAEo5BLnVb5sCTHR42RKD44GU/pkqs56XoJiuroomEFeM6sT+pm\nTGVi+2ivwQp+pV9yGif9mepl9II3RfCHvJyZUwdOhJqviNhq+hSMq2rdOHfn\nPL5g2YKeInxj8z3MofAWm7svveNyRGOTjhTbS+5AZTkFime7h60CHA7dEAth\ncLHXjVTSAfQ+wKL7FZrnqMwR9cKkbTllU/Qebt8UIXldPOp3nk/QeYERjaQ2\n8ck3i8Ln8jla0lpD9G4b1pwEHQmuPYKaV72xwMWEk+KViSjMm/81hlVpsqIx\n9YCcjPrDg1oWpdSxqm8y2xDMpyrTYHTi7Z44be7SzN5zqiIdNQg2aqOk/GCC\nfOYLBHxNnQ1bzB/TdlLR9bCl+k/24Qr9qbEL/JLR9vVycqQApxHWhJW04PLV\nYlKr8jjRw52WgweMGxTsgHP0CxK6rnoqVIAaZCsU7KB3xY2DJT7xoI3N9vRm\nu5OFCbyqo/Uh8mBwCoOXaUlsTdvridqJ64caSt1NLb/dmdm8Np+lZkiqs6Tp\ndEB9\r\n=9q43\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnuuainvVy52PFAbE3JDQ7QiEt9EODVfpif+3vb4RSuAIhAOUVBZm5ZpnZGekxrC/LYE5AMPGvt3IityYbzAaryGPz"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-cc4aba6.0_1589536834739_0.6169177608641292"},"_hasShrinkwrap":false},"1.0.0-01ee951.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-01ee951.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"01ee951f228a0fc98c1bbf04a2d62bcd9aedf282","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-01ee951.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-GkxJusclXhcthoIvRNkvlThsbLW5Lv9eeCcYdO7x4SKEsm0/pLe9Hn0JAOPlDff4m8+jy1WBHGkNjObT/UQTUA==","shasum":"c14ea08f5e54a02d6eafd4c66246091540accac0","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-01ee951.0.tgz","fileCount":367,"unpackedSize":62716697,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevmhTCRA9TVsSAnZWagAAAQ8P/2zauE8rZpXRXOrnkdJ/\npxg1NWGyGUzA690DLD3TCIbpPHszivaQeeu7AY/gTF//M3pdWzb/qDYDTwD+\nBap0Sso1g7jnayU85L7zo43FzcZfmUszNlI7vJhCqaAad9+wdTTomx4N8Gt0\nbsZQnN1+B3/eGQUiusdN0kaYRRNhQTiVIWmIjLbT/0N8KYbRgilAgwcK4NQm\n77r7nwx4yGNRr0zDu9Fp3pI5ON9VtkJPbv98tS4FLHuWbplwV62DW+IBKeDu\nIpA6bWLXN5kIchCLKjuJk6BRX1BFNDhfbJpM1QccgTKXfH4GZ8tSEPO6q54o\nS6ZXSi/eJcRjfvaZjw3oU6s8k5yUYdj5NNJ/W/IzaCv9/VhDd+I5s+XpUExb\nGoIlDiPCFL3BOo5cubnmYRn4iCp9hopQmhEUALMDxw6v2X8KeG9Onpr9cNl0\nC5PcRQGTQKjg3lW7mYq5U6zYc4VaMPlOxPkN6201DwDmpdfEN4qKk4APidvV\nrEHUIO0Z0mPx/KxgIJSt/jLMEBjfFamCAs9yhyKXa5E3U/ABpUb1FOYrPBko\ngeuyF65PunGp5Uh98NjPg20C6YqGXw8ey39OoV4to8vrEq9UEBnBr81VYApP\nScENhKhdA+ePNjY1q48Awkcm8Mx10f2ggehtX927SxHfeS3Mu/DcgUMnNR3T\newCr\r\n=pkn8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDRlKBQk6jupoQyANLULyRogJlmS+Z+DkZtNYaaYyy06AiEAsXMaUBvm0QOwcl38pI/93TiF/isCB9uxYhJv9K6RIgk="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-01ee951.0_1589536850884_0.8644739746249177"},"_hasShrinkwrap":false},"1.0.0-84750a8.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-84750a8.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"84750a8e80b17a48bd32b9f63ee62f7e32cee9fe","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-84750a8.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-SFxUYmZspVV59d4XZ4APghO0dzFtqimu1G7mtcqlB5LrZ+y2WcExWtbPNivx38GWBbI316QMYtCYALo/3L9OZQ==","shasum":"dff76631b0258b2d330b65a7ae27aa92dcbf9b42","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-84750a8.0.tgz","fileCount":374,"unpackedSize":62834343,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevm3OCRA9TVsSAnZWagAA3BMP/272xL6641KgPRdxCUpF\n+fnWVFM9aHSMH9ZPAkroTV36I3yBaoa7sWLwgn23Px2NJkBWHN6TOj4P27IP\nY7eg4SjgiXWbrAiukfmT6tVt/AVuxUAT0cs0MWNiI/DDnkWPZ9aS1Zb2usMz\nmS8NB4JeT56eeicTEYr6jYufY8Y+m1pa30SHZEMou3NFheYze4s/QgN6yGz1\nWavLEo4mA3rwIvn9OgVtywFpZx547jsRb++KfH2TCHKsZn6qMyiTfXvy88/j\nY14aIUtD0+kOIq9L5hmRzRDNlwoHlIop7N6AE4MHNUeHayDyIhH3ho0T2aBW\nVvG1kg0uv4uGJyefCIoZpiyYwvARYAOBs7TtwPcDwLg23mGc0i6Dfp7Gdpje\nlea2pNEtI3jpuaaNSWuA/kV4wekZ2MUb7UbgHAKWlXyk+SxwKogWwCieVbBW\nxhpTUXgeENj0vc91b4MiIxsGXmRjKe5ttLAvV36YUGzbP5Ytusp7uXZUJqq1\nNhJHqIinxxoga/lPj4tGwiNfHpdq+GJ73qWYwY9qGyNL6wf5kbhxAEmhSXyH\ncaRWkxsIqEYdEAJkZSAvgLTSqwoYrtROEBDWF1HSDcmLbyD+qx5/xICm/zOx\nHEvrp/xmgbFLCZlGUitXcEi276oNYfvuCGY/hPTAgmi/2S7P5ZsP8ph1QbFa\nDNmu\r\n=eBnh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBaKd+Sd6kRNcqae2adRs8AKR+hMv+t/dt5fAHaX2R/jAiB4JkMUYhXnn2sHjgjHouEjT+IyL2/rAz1rajsKKBjknQ=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-84750a8.0_1589538253908_0.7700130418206474"},"_hasShrinkwrap":false},"1.0.0-047e339.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-047e339.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"047e3392c2c4242daaae2a536b56297b2d01e963","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-047e339.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ehdqUvke35+iN7kvNneS4Z3kcujUMmE16lTlTE0W5gT48y1aMeKO7B1/3bc3SpAJXAkDXpcws+RKjbD9KB2ZkQ==","shasum":"2930c9ee6b994260d9f16b2989396231004ce107","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-047e339.0.tgz","fileCount":374,"unpackedSize":62834343,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevm6VCRA9TVsSAnZWagAASWsP/j2IRC2uX3H7UE0HcJ7m\nYAnZxxKykAW+ncJELEKRVofb/RGOJx/OcKGZNxZTXi3vtbvm0RAgWhVGl9n9\nwVlKXOeTXrQyYTLecdoDbicE403YmN5XczUnPS1CgA9FzjhjHOwDpHqCl98v\ncI1zeCMIEUwpb/o/+nPsRqGlVphsjtvVY/AYqLPCwSM/31J9kFsCwzEL3yZc\nZXTxx5RdrPdCjaZ9+2WXc/EhsZpKCLq84j8lTWjKsC8wjHjVN23p/Q2LvDMi\nuvuHYXMnUzaQTzEGDQ3uFbjGBXtM3R9RB2G6CuyOXBn5bDBNvcmdd/kH4Etf\n/0Yb2Ps832oFLb7yBRr1VGJgVN8Z2c6uLESWNg0JEhtFzt4VDd3r8sRYfqdS\nEm+kgRyvt0NkbZlrWm8GP1QI/4pkBwxzE7NRCmpv3Vw7Uc0e07f8i5M94IbA\nO5E5c69Lk0+Nz4lRw/oH+HpQpgD+3ZDFFFNL0g0Voe/JnHnRPXsT1nTH0XbO\nJcWD2XgNrceEcRqSKtxgfi6q7ySh+YAFV44bLOv3apFt9EWps1mTNn7icEuh\n25Y5ehRNrA0K6QRpy1SXMncrOjPFAV1ZCgbWQuvmGtMVqjzjtOMgw5BCdmTj\nmUsCYG7TzImsfuuLgS2hOL4Zr3Qy3dOx5j3SV+IheA8zHnODEjpTDvxS/e9K\njGJF\r\n=ZF/S\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDdXCvgsyLb3FztCX6BxS6WTh6Za11G8bltO+CLq7avMwIhAKCn+KU4Z7A18lveWPcVVGT1gvmFpLAf7GZXmWtI1b9K"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-047e339.0_1589538447769_0.7291657676995102"},"_hasShrinkwrap":false},"1.0.0-d7aa107.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-d7aa107.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"d7aa107f896c8fc9dc75a1ee93401eae79674567","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-d7aa107.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-pQuHsLk6ebGCZyeRp0JRH/zqhGkieyCDVzVP4wREBs/NXEqzxI2JcBllgaU/vtyn5/8elUZC1iwWKnTI8LjbBQ==","shasum":"48306533bc48854aa31668e59c2fcc2e16e0d722","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-d7aa107.0.tgz","fileCount":367,"unpackedSize":62715865,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevqbrCRA9TVsSAnZWagAACV8P/ipoN5wYgM9Ib95dLUdv\n2PmXHj0SVpAQMbLAce3dCl76Y+jxQQAaeFMfXXxQBXJk7gcyp2Nag9DU7hsI\nwnuomCXZb+OUBySxp2a2m/X9A3T83oGi+wFD5sUWJTViIBZdvf6w/Yp4wcqx\noVJ5m/5fVU/vt09jafF4RkC20X8R0pKctYt2pylu0DnOQotSfb3qsQayEtz9\nIGZNbNqMgZzmJQi9raN0Jgn4TNiMQzZLU1kG9CIY23oofKkHRTxsHr0/7tLY\nism1Tyz9kpLxzhuMhBHxf7D0swm15P+U5A18q4G7Qn0XjUOIUAILV2ezei8J\nY8dQghAo3tEYktXOcJevWPp1ZMuAd4YeKJqsZLlM0W4TdGaTmBlAmrnLZsR8\nykLZyLTk/S3j4McGRrcpJlqCeQbYKLr7KrIKfwdd6FY0z3Z1TWw0Xyy2wXB0\n9buU99LIp2y6RHdj9DU0rcIFVl4UorhceIkMWJt/1dhk7MApIX5jDsqenqHM\ndMoYBqQmg8VARNXtn8sEvsmPwAsDwjNlufH2gACv/BrZbzTK0j6DvFnMwkD4\nh9y5xMBEhi7VCO6KD30q9MLuCT26SKGsRW8EpevpLg5iMsxyI+qUlNUto3WH\nAwnjEX0IaRXHnCifbp5IHzRKDXuu0C4cnt/N+V3YS9LAeLvEANAtJADS22+7\ndXgR\r\n=Wd9K\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDcZ1ohLoj7WhRcXYKgXzTJSPKTnnfzc2Ea7Bh54QGFGAiAPLDOhZdj20Ejpu7g3dQqaSKFyosgspTUg3IaEpvdC0A=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-d7aa107.0_1589552874397_0.04590586490939841"},"_hasShrinkwrap":false},"1.0.0-468c15c.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-468c15c.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"468c15c714435522eabf4a95f41a821e167f1598","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-468c15c.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ktrQRB1COwv+xgjrx42VylMzuYiW3u1tZZXI7Ye1WBYvdriMgWuDMTkZy1yJfK4430ELnSc0h07BuX302bhynQ==","shasum":"a82c2fa1848d8cab15f6e4d258493c34c71c8a2c","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-468c15c.0.tgz","fileCount":375,"unpackedSize":62690400,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyMQ9CRA9TVsSAnZWagAAMGcQAJy8+SwKb/X1OaT/B/FZ\nOYKj1fhzyp5AH7/LfOA7lkTPw2pUyK2R6o5oduj/9Cgmn2QFGU10NkdOIBC3\nUIIk+05E43E4jKljFaCPy0HnBgeesMYnxqDSNUIIudVTcP6Bs4GQoelpGmIX\nVyzIbSVQTmmv5gywtsmci22fCzx84dA7fhAGY4/jkBHiJyx8h5RRm3anAKCU\nBULEUmKVSKdnpbIaaQVZ2RUJYryf8TPmpRBy5n1pOnPJbaqiRyeKYeguxHFv\nGOj0fssW+fzW0mN5DKevSmdJggaQmhV87fDvjsmHvzA6cCs+4n82GTkd8fa9\nbHgt4HgDO+qW4Zo6m5heCLqVdtZx+1MMPHVpkznRasUX6cS0FA/xUPLwH2v8\ni70fL3dnAVYTtXLChWR0zZbau2M/HkLJmnvtAZZ0qx6+f1fnbPKQURMqc/8r\nS1aMEfnGdZArli6QugvoIJ4+ksADGBZ4XrUHzi1htcp8vF7jUP1T1sqCk/Mm\n9PeHHM/yRaJt38NKsyxOBWJOlpxG97V749NdWujSIs46BnHf55Urz+MigFkr\nE1rwHZAqLTHvcEO/tjj/sDTkCgtrss7TypzbT2Cx+pdwJ69xOS2GeR3GJ46u\n67Udu8y7vffGqAKRmG5E+7UV0lxclGkLS4ptrXPSjv0sm89bgff//VTa3Whi\n6uus\r\n=TBYD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVADJjO749aNCIBRQrsMAygTjCSXAw/ZFxaCTf+DNWwAIhAPbeaneR8NPH8/M/qkSdewUGeM0mebLwPDaocHZJHuoc"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-468c15c.0_1590215740609_0.6102091715378553"},"_hasShrinkwrap":false},"1.0.0-d6c9fcb.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-d6c9fcb.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"d6c9fcb7ffea1e6f07dcacb0ea89b1756884f0e3","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-d6c9fcb.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-iUp3GW9Hd3Hj6PaDmA6//qc8iUJO5k+U0Qk9wbafwBp8Iw0olDGlkUjHwh17BzxVBgr7/5lhCEU+pECtQO8gqA==","shasum":"8ef8b8c41f6b11a101103f1d16ae07bfd108bdb9","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-d6c9fcb.0.tgz","fileCount":375,"unpackedSize":62690400,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyMRCCRA9TVsSAnZWagAAYEkP/2/YDg8w0+5vZoIXTKjH\nOJeueEcmO7Vtp4YVPOdGzABcQ4KtHag50EmTjWXz4WOE5haY/77BDvjEER25\nu13kVeLPETs83HoUeN7gJ3xa4gjnIHJS2xOADCMt+kx1SddMOccAogpjmSiz\ny/zLxMsG4XyIWIDAO3OgQIVyPkTVYtLIBat4xOGNP9WFfxIjY9B4HbQdBmK4\nPUvjJXnKUMIZQ7qgQ2kHCRXV3iNVSzRUQoKzcdJGP/+pU0tZ/2J4oNx6lUAd\n4QH/1lnTvVtLcrjpsx/vD1DV26CYZmWbSsnKCWd9RjaZNQ/5lRFTafVS802w\nWdl/Iz0p5YwfYoNzNYt9zNWktaDo3no+QSjS8sMT8VImPW2MIRo1WyIu3EvT\nfaUTW2YQrjjTY2nqzRinj+pupoqDFsRdpP3yncfWCX/NYjQEW/useflZGgNF\n8OLBxZUdQ+9p2V34IaLeiX6V8KpRb/UjoWpJQLVxrDnHsFTjlFQdATbsQ4Ms\nzjfH/CojiWIg2Xw48ad+56HTBmV7KV/y0PAwATX75/mQ1bsPIIds0zt05gnN\nrxjW3LmCAcWl+giHUzEL/oHKSpfLRnLDbLyKd0oFGJYqubV4L8fZqd4d/he2\nYf9nzQ/xwa9sURWv4sJIU1hj/gUVJPcawGFKfTVnIM4XBm8b+rM8fBTZ8Vwh\n6wxu\r\n=rKEA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD6s2w1jwfIXWEEXW8c37hQeXeJVbXZPySx9LrBQ6ONQQIhALyml/d1wZKQc/D98KEWMzJMsUclfRw3Fvv6nsyWNyBt"}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-d6c9fcb.0_1590215745541_0.39155377537558667"},"_hasShrinkwrap":false},"1.0.0-21fb677.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-21fb677.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"21fb677382ee9cc465cdc68f93ab3d3cce3fe7d6","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-21fb677.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-vYml65fc3Gd3/OvylL715idR9G+SJbG6YTayYUT/EuN2RbStRfWEGQIjx1xZPedxT8Aek3abjfsMQrFBoNZwjw==","shasum":"4a04d3284c4be36797bce0232b5bf2452dc90748","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-21fb677.0.tgz","fileCount":375,"unpackedSize":62691018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyNIPCRA9TVsSAnZWagAA6DsP/1vXSTvvaUW5M/JO0DXR\n4KsLtro/M31UTi/BEY75NsY/3THZ83kiW2T2ZZd/P0r8foEfuwfobrZDtzup\n57SjSDvLOgILV9xqfaqTpuR/P6C8VG7LAUa7gfIxh09dkxTnt8eSDCzDyjRw\nppyDk7LAOh098aBtdSVV/OJiZQ48V7xy1k+crcWI8Rx5CaURYGsEc8jQ3CZO\nwyzt8x069s6kyWmmahSQu4gtB7Aoq5Hg+LFrTtcz0tKSt8RxPvIzrBX5Et47\nVP4SqtfXkk+f7EputGSh/ahyAmsKXw+2LkscgptLQ4ErsjjifGQuQvBSUfJ1\n/Jofq4pcniDIjrS8qM4ktSueHwEluk0+puvrcreda9A4v8fIR+hr1xIcMzIq\na6yqiMAqfn/Brc70IgDbXqgs12yNv5MVT5v5X2lDJ/wdNWBnu5J4lORMk7hN\nJWsO3izI97mtbb9zCRJEZTq8srDYazolbdvPodmgMxTaUV+5rCnj0QsGv+gP\nwDugQXcm9uyfY+9w9ANwIGORlF4lHls0FIlkk0g7lCA2UbgTrK0uTbLAG0zC\nBCtP+zUnl+vABrJ9eXtW+enrRoNhP2LhEn/Rn3NMAabNxaRXzJ/SBo5qJvns\nJdsYcgSecpQXbEBJ3+vMmUPGaec0j+ggSkse95f8SeGTZ6MHSaBdA9BJBNE3\noF4K\r\n=a06q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE/gVrJdkQJvltAOVFjwR090iwIA8b7nAZRgq3OhlauEAiByJT5w3ZeICQwmQL0XJs3VJbN7Z4Sx1LarqDeVOTYSVw=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-21fb677.0_1590219278664_0.5831950903802625"},"_hasShrinkwrap":false},"1.0.0-4ce846f.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-4ce846f.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"4ce846f2618565ffb911a433c75f4a7c70659b5a","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-4ce846f.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-qqO78NCzOGAxxJKsHXg2ShTyPt+W7MvLQ//+roSGMN5IebFjyYOM4JI0ch0ZHxeCylp6kS+ZNNxXQwYUp9QQhQ==","shasum":"9e282afecf6faccd6746202b223e066231fc52f0","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-4ce846f.0.tgz","fileCount":375,"unpackedSize":62691018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyNI6CRA9TVsSAnZWagAArlMQAJKSxOzP17uNd+14BI6x\n1Kny91B9mAoEglSi8k6KyESMB+x+Quk9Zy2n+tvblDJuHexCZtRfa2GTZ5Li\nLqp05l0FsYF0LzktAOUo2vKm9pRqzOg4NMgQpz0sViVW0SPzsMqbUuZGpVbc\nHQj6oNFfLCYsZoEhRrs0+qndp92fEf3n7DHr2xvWHZwscM4S6/dr8F2rfxgi\nHQoJwXjHjzcs3nvUb8mqJUSvU02y+iGY4Xc1ei+EGU1qefhezb4b7ag+D6Ez\n472oy2FG1AcSUg5We36IfHSFwHFEi1Q3luamV4UEllNmxFrOsCFtfipHICts\nyiCSHUav/RO4biPulcSGlHo2Du7w2Je9jlZsdb0EZQiah1S5tjZ/lwC+3Q05\nAjC9/ZoDpDsxA0wvbmN5WcTsyVHivVl/Rim4hpfFE3PLzYqfj22DVTtWkGmA\n2BihMyGPAi6Ig/dpsJznST6OXYz8OJhfjMh/Ig3lXGzUQGmoMu5flgbw4Gc3\nhm6/FPmjOMwtSkn8erLGhfGcOAHyFVv9KHC5aZpMGkZLnEUtqYv30HHFeTb2\nNyX4PfrZaIt473iU/yxgV8AOiIhXlS+euUsnCQV3jTrIRM7UxZVYE7pDZLhE\nZGMigzkG1HFEUsag51Xd2iV/1A98GF5zoZbFMZkGHDn/IrdUcrvVuOaT6QNP\nEZn3\r\n=oy9X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxHtCw6AcE4JqDvqxkf23+XL7AfbClifwZg6pozV/eqQIgZc5NYzyLRP1/pyvd+d5L3gD95JdRNmwZHENVkVlPFOQ="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-4ce846f.0_1590219321330_0.03663302934877355"},"_hasShrinkwrap":false},"1.0.0-fabc034.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-fabc034.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"fabc0347753e8493cb2ae2579928e82abdd56659","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-fabc034.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-HZjujunXpqwX1/6Wuu7Pnkoz8sAY/jr82m+GUE4CdnW4PPQ3hvhBVfnK2Aum08lyjQ/eBM+d6nFniduJOnLfFg==","shasum":"997c424d868756ebfe6b849916e2dc4184653903","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-fabc034.0.tgz","fileCount":375,"unpackedSize":62691018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyNj0CRA9TVsSAnZWagAAv+sP/Ake3pUQKM6Xzj7eTQj6\nTkc1hIwi3ioARhjVfW8b+F7+Ke5CXTOPUaYC+ZV4CPjNvYghiAY3zkP5AUL8\nb89fx8/lHgEJV73NUNSYyoxTiagL1Z18VqAPH/9JpOZQpKwzyDuM1HvrYJfK\nNhl0BHVVIjVBSbDnjIXdyobA8Ex4B+OzPV8l6pnWpY3v/1S9ycBcMtQEAZUW\nmtY+KgLBBzLSaye0KdvwhcUFpBC88TbD+ljnoTC2ekcVo12uZv9KaAHGXnrz\nA+nmFUrNDhhQ4gXU02SJV0rG8LQMaiUG4RWcqlHP2VF1jyNHAbVP3WLrv9vB\nSZRY9z+xEyUdpR1ADkqJd5zrP1Eh/LejKhFSXxb2x/jsF10cZAA8wmCRskHF\nfSz5Gegs1WdO1uqYsfEci6TdEoKgKHKb/PpPdlPR2MP7LnZwLdjA/caf4ksz\nDeds2qYdfuCicPABdjwOyIvr6GdcXaZ6qcfNp0RfeR08mBAp7L2EJFAqQ8ha\nnA6Z/092YVJSghPVgJrECrCBddUEhQjoZPXWAOR4vpAyuOOzsOhCbrIc5wE2\nNfLofARs6IjW8iAEDAbmGn1hx5yHc8TuQh+LJ5aucZcoRMnX2dxOpxUxqrPX\n7deg+NuqXevzn3GQCioYm/CILpb2m1YfGBoR5k0UhnkfS7+BFz7Qh3rB8UwE\nt8SM\r\n=SUbh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC3FOmNKQ2CESDDmx64DkuDshREtapCAvs/F/dS2FP25AIgHLdH0opNPPUdh3ttK7mryXzGkvEUGLhMowGg1eJJ7GQ="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-fabc034.0_1590221043964_0.8964591982218866"},"_hasShrinkwrap":false},"1.0.0-03f3dfd.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-03f3dfd.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.1"},"gitHead":"03f3dfddd497b03514e2518c2f913f9b3c689fa9","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-03f3dfd.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Pw+cBVgj6bqVzYMOimQ5qcSdNn+O1DZfqtGN2ywCR8qP7DlGGOHeIXZqcAh9nx4xa5eSgiP3mwdjJnHeOZ4GCg==","shasum":"b43a525fd6f91ab5d860ff45d6e7367d16fdaa1e","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-03f3dfd.0.tgz","fileCount":405,"unpackedSize":63142787,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyNr2CRA9TVsSAnZWagAA04YP/2eM2x8fnkf0BDbpAeRJ\nuAYuxMBwSwGOk3QBxzf03iTQLVcDimcNl/Ia2GvvN04pGB0ToFo146tVErjC\nPh/LJ2YDq+VrS8UdtVD2YKmmbRxyxxX6CnTPNcX6KdDmohFPA8sCIkGBPGpY\n4iXOF0fL8cSvCqoAdqF/BDr3uIcKa0r7Ue1bAIyKmBoIh/48vUIVgoigSlzm\nHwGAPBhSuciNvVN8AUHIiPLXpUx3L+N6zTUuVsB6bYZQEa0mzcQN/V4yg0Zh\nLFTAaYRUd+n7tkFKZFn37i0QNNtv2+m9X6bdJHNoaQrKv3U2BP0GTPq01rzc\nALyc5aEDv//mkzE6EwqwdAA5ac6r3sfipjDUimNbfWfMyLRCZKuLrx2dGkOo\nWqRU3WrMPynXggFQ+E6M12Gr/91+n2sUYtEUOrQdOgAh1qm6mQHooM6YRfel\nTWGbC349BQjTSULU0YtxsK/UUdmye10Z3te4v3iIe7RI8mOMYkWvBZHnhdhF\n0c5QEWRWJV3aZp/t1i12rVbOIOPOSIq6RwYshwfxuXxRe0Edk5h3vGq6s3Jk\n0QhmmBE8mPq5x4kcpqeW+Vw7zj/KIW5NOBUIxkqvzBYUshtK13O7C39rfQ8R\nR+bYXgn8/ANgfmUjGvDWbipvinsyCdXzkk/ZS7fZ7bkIP/h1/T5SgGM5e7Ik\nLe9O\r\n=5wh6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDfAC5frDuqyJ9NX0le7t7sKBFoT2qo7PFbOc1haw5WDgIgf9IcOAs8B1Agi2nvtaqnNPdZdo8udx/8Qan02f4WY+0="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-03f3dfd.0_1590221558157_0.6583677800790566"},"_hasShrinkwrap":false},"1.0.0-aa8412e.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-aa8412e.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"aa8412e209b2eaf5b42044c11c359ca7b1362acd","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-aa8412e.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-HRVspHGq3ouWlEvhpPQSk4ytlnT1zWRYM21MWustkX/dB9c8J78WzzmkKTbpjttW7837icQJshyCZqVcDnDUjQ==","shasum":"57f79748a3f7b156bc29b96e557f3df6f6082657","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-aa8412e.0.tgz","fileCount":405,"unpackedSize":63203552,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2fshCRA9TVsSAnZWagAAhtEQAIIxGe8T1sHRIhBGmNzn\n9BmneKH+yphGNCY21RBmjHKjAO7YTrCv0VwI9veS4Z/xyeE8ps84Qd8zVQfY\nUSDfgYIcCeQMIYun86O6vZfNAR+oSYgLUkzen8Lpq+MEO2Ir5k2xr1XnykrD\nyGIuMZVv8RS1Bp3pLhFgbUafd4vNCs+8m1ht8KAM7ll7VaIRtRm+O/zuN2a6\n6tzduNSO4gS3xQwrwLyfOrJvDbobLk8dLgNUUpYa5R29Kfle8bRuMwu9dYrI\nW/dRoCfq2yMYUdiq9s4o5z4Z4BhpzGL/aNgp3FE9DlrC56JdMwTTXEzTSI8P\nEcHc6wmehbo34kw8mYrpicuK495e8TilU2rY4k4EJo8LUfoULnIl2+8R6l6i\nsPPrzgK6zZn4OoCeUJmVJGZttM2qAv+ZmRaii9OwdiS8gQIM5I0WpzNhWuIm\nql3ZXk/rXprz/323qRAOvROZ+1ik8pSGHNb9nWOXm+ArrchhretTX2J+WzGf\nQuevDrZxcMLtNL6Y9454/P+ak4t8IqXpqKueubQzb0TJdqEnKQXwjhvwIvEX\nbvYAvWzYsjhHD1Gkx2fqrp1nfNh6QMtIyZI5gp+PMgm/6fjUwS36LHhTxhu0\n/QhwOkSvv4MMoUsKvc//waC85pSu96xlkBkLwTgalQ/ORZenoFDHVELJ2W91\nl2sE\r\n=9SB+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAJJ9NrFVZhMhsuBV7aUzb1uUjTx1XB2X+/EXzok0mTWAiBJaIJUFKmAxm2ZDgf3gkuiRlAdi5LGy0B94QCzaBLCEA=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-aa8412e.0_1591343904772_0.24312520821509764"},"_hasShrinkwrap":false},"1.0.0-115f639.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-115f639.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"115f639718b50ebdf2f3f63d712763ad20ac9c90","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-115f639.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-jbS0HWr3VkpPjO84gangnX48s7VHzbG14TvIr+goSuvrrutFPu6G4J51Ah8jPYDeYEXekNwWpQsfEs6yytFBXg==","shasum":"103ffc1ca48b79abe835684833532a0c603d9d09","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-115f639.0.tgz","fileCount":405,"unpackedSize":63215702,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2hwpCRA9TVsSAnZWagAAhSoQAJZ43Z2hWP0B4lZb/ZLN\n7AJUXBh2/LqaUtPMiP9iZaFFTDGiVFDjwkIrTg3wYY9StcwH5fadZvI0Yken\nFieDNvk5cmmJ6WQEyOQwxQMEwIkXfPtrzPehiQL/V8kby027p/IW1iLLd04/\neniUnPjMTdoS2/Sm5I/6kUFb9Ifo6NQC1DuVelEKlFdhewnX9bjYvlzeti7L\n7qC4Hmh1552gUkgGfw4qSI1Kf7uDUlz8i7vsIJnL6qsT8ye2LwGA7QWAc2gy\n0wJUzjaChu3EkL3f2ji1plDK7XU+3ElM/PmVUSefSGTSwKj2a0TC9K3sVSjk\nFc2ivAXsJ44NKKwy4nUhENv7dt6y880Y8oRYfjG32aTYmSR4JVFHVhsMhGI7\n855wnKwP6YbWbz8t0kr5lQhphgXammuUfYkqP1dDtjcdo4nYVm99V7OWq9V5\nbiNjPw7qt3n0/GMeP4T0KJPVE/zMylGG6M61sfOUwJwTM829E6QOnAUuqlL3\nFfbPrqyIuLIYaJB2wlGc99U0GxbEAtZFDoRUBOAtd4TX35neX0Sm02D7sdan\nlLOVqe5WgbD9ykqJ5pbAKHhw35QZN9Nd41JlimaS7/l00J43VarD2t6+ScaV\nIW7XDVIbZ+pw9F1vtn+uvAdXHId812xIMyD5VaY+agy4/l+eZVJzDE14xH4F\n0ae9\r\n=v3E+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDvinywJh5yyIB/OogjMDmGYnoV9QJquUbGxlC+1APzUAIgM4YzaQqIRYIz0LZ+tcxG3cOUL+PE4F50k+MOdWC4KaU="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-115f639.0_1591352360505_0.44423353873031823"},"_hasShrinkwrap":false},"1.0.0-d3c1771.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-d3c1771.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"d3c1771a0aff69d224a8d86456e9260b5b1e9d54","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-d3c1771.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-3f6qzu5JsqLgi+rv7XnaI0AMm99nPjD4WX8mniggV5ryIwlu4woWercQsSwR2sAXGNEyGQny2gRhHdsikYQHOw==","shasum":"95fa42971a529fcb015ac0e0932b873f00b5e4da","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-d3c1771.0.tgz","fileCount":405,"unpackedSize":63225838,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2hw/CRA9TVsSAnZWagAAZmIP/0E84Bq6oC2d+wDgKcLg\n2XBs9qh4x0Tfb8tNRTpWvYsA8f55j7rW9JBXfarHMw3rVcMrE/renjSbFFiW\nk4dT3yPhe6pYiv7zVs48H/nbX7+WiC5YhncsyNh0l/zF2/xbRSQLTv9yc+mm\nmCbKVmHIGforbgZy/SBveXcJKtDbNgFS9ob8GzPoSCREmnzkkmQaZ7A7/EmD\n8b7N4wcjxci/bxiSjqlCKawZkqte5czfKb848mrxITe157cHUc11KZvqhKRD\nLxPH5CDpcx/YTW6w1CYYFOj7NAM0lNBgzUWBdAVmWev18fjC6QnYAd1T5WWR\nflnpN45AoFHXwjMIe02zpqwALRd7taSu+qFtF9N9JHpC12MXHNvorYZh/xaq\nJ02mwyVyQeBbsEx/EV9ZUPg3YBMY9VXOFSVi/x/CMLgdEmK6cyLjWfr7g2nZ\nNaTWIIiOq/v5vJtx4wvurMrvEvNJyYaVgNaA2pBsdnwQaEbz40W/zEEoCdM2\n0UTRHunfbKV7qsME3G5iLRwhifW1KvekWOLr+C08CZr/wH9hme5H3WW50Mxa\nrosn0p/8pVFfOSNU97vT8Cng1k3Gz9AWAG+JJYqTlTgzRP4x/hiuhos+D4ZK\nYvwH3Ebp5ZB3JSShDL1ukOKfR83INhvGtS3vvxzGk7iry/gztKiSncVr2hMi\nkW8+\r\n=TXfm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIASbyqlYobZcxsVb/YTikLdMERK+tZnG4eZIDrEdl9ZIAiBi94vICt6arb8KEo83mvMp4hOp9w1KnMog+PUTsJsM8w=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-d3c1771.0_1591352382616_0.904015730479345"},"_hasShrinkwrap":false},"1.0.0-23baaef.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-23baaef.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"23baaef3b00584d33cf79475f3e2e046b9b93df1","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-23baaef.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-04KexA+jCikfRrgT7qg0ZcynxBnJ6epZQDSsA6MOODzRpF7/k3vvXNLqZX0GbmWyaznWXbenwg3W4tNUJNmOgQ==","shasum":"4184d49ec0fef0eda0b1362cb46e10b84751f995","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-23baaef.0.tgz","fileCount":405,"unpackedSize":63068296,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2xrDCRA9TVsSAnZWagAA0sYP/iAy/Ip6ZjWDU643/bca\n3ZX7x4I/lBBM27G7WZUnFJNLBiSW/1r9TDyeDrWUC7dAJzKTJXY6LpXbJxU7\nNwRndhnHUy616T/uDePwIC3m3rsje2kSW501EOv7H/YrjUUTXx5hCh1h7Jsb\nPBkKI/v9nfIKyrpL8+y9oJB6ktgUeA2TJ/LSRfuGfIpsISIaLZi9y2Ahi3To\n9LMLtyVDnKglb7gr+gzoWDFZRsfYpCntwB2qG8NeAyGpcV7ZJIITpNOZh370\nwT+IplzgGJJ1qMUj3cTnGkBLRFRu/9DVmG+nOecM8otJxZtQ2b/0w9phQftv\n5sPibULvM5+v8Xjw+87YAoCdeELJNU4A/Ooiyyv5n2FX+fBumZs3irHdwWTQ\nKyZrH9ICTlE0ayZmOzs0yO2GjwfSF4yRJhAOrJB9JAQdIGUsjzeGuQltG5a7\n/uu0oFwb6YyD3FcC9RqWWDcCv4dkjCP3Xei0LH9ZAfJeikT/+b9GS1J/SKCi\no8WL64bAZrj3+NCB74Gxb27lHmOMU9bPYlRMBN55f5ZB0tjfccQqLPDqTXhW\n6sBqfiZUFXyTtS7Ky70Jl5k7sNldOlIdKqaBdu2mniJPlQxhn43nNKkIeRag\n5Y3OUS3LfdSi7S862AvIpGPZgHyLOjCEQKANi2Y+wJ+fQwXkrpb0QTF7EzsO\nFmnN\r\n=SbHw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDnAby8JUIiZyxe2gZ8e1ilDD+GkdgqGvKSvPZfeZaKjAiAlhzd4lqJgphPrQOk6o1HB0kMMwzeeXXrs8h0jwk8h1Q=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-23baaef.0_1591417538641_0.19632138723354897"},"_hasShrinkwrap":false},"1.0.0-619d0df.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-619d0df.0","description":"GraphQL PPX rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"619d0df619fc89f21b16e2062dcf570f0879f898","readme":"# graphql_ppx\n\n[![npm version](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg)](https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re)\n\n## ⚠️🚧️⚠️🚧⚠️ This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md) ⚠️🚧️⚠️🚧⚠️\n\n> Reason/OCaml PPX (PreProcessor eXtension) helping with creating type-safe, compile time validated GraphQL queries\n> generating response decoders.\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n\n## Installation\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re --dev\n# or\nnpm install @baransu/graphql_ppx_re  --saveDev\n```\n\nSecond, add it to `ppx-flags` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"]\n```\n\n## Native\n\nIf you want to use native version edit your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nThis plugin requires a `graphql_schema.json` file to exist somewhere in the\nproject hierarchy, containing the result of sending an [introspection\nquery](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. The easiest way to do this is by using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\n## Ignore `.graphql_ppx_cache` in your version control\n\n`graphql_ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're\nusing a version control system, you don't need to check it in.\n\n## Features\n\n- Objects are converted into records\n- Enums are converted into [polymorphic\n  variants](https://2ality.com/2018/01/polymorphic-variants-reasonml.html)\n- Floats, ints, strings, booleans, id are converted into their corresponding native\n  Reason/OCaml types.\n- Custom scalars are parsed as `Js.Json.t`, and can be parsed using the `@ppxDecoder` directive\n- Arguments with input objects\n- Using `@skip` and `@include` will force non-optional fields to become\n  optional.\n- Unions are converted to polymorphic variants, with exhaustiveness checking.\n  This only works for object types, not for unions containing interfaces.\n- Interfaces are also converted into polymorphic variants. Overlapping interface\n  selections and other more uncommon use cases are not yet supported.\n- Support for fragments\n- Required arguments validation\n\n## Typical use\n\nGraphQL PPX is a utility to work with the GraphQL protocol in ReasonML.\nTypically this PPX is being used in combination with a GraphQL client. Popular\nclients include [Reason Apollo Hooks](https://github.com/Astrocoders/reason-apollo-hooks/commits/master)\nor [Reason URQL](https://github.com/FormidableLabs/reason-urql). They also\nprovide a more end-to-end getting started. This documentation will focus on how\nto create queries and fragments, and parse responses.\n\n## Defining a Query\n\nYou can define a query in your ReasonML file with the following code\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nThis will create the `UserQuery` module. This module has the following\ncontents assigned:\n\n### Let bindings\n\n#### Basic\n\n- `query` (`string`), the GraphQL query or mutation\n- `parse` (`UserQuery.Raw.t => UserQuery.t`), the function to parse the raw\n  GraphQL response into ReasonML types.\n- `makeVariables` (`(~your, ~arguments, ()) => Js.Json.t`): a\n  function that takes labeled arguments to produce the variables that can be\n  sent together with the query. This will also validate and type-check the\n  variables.\n- `definition`: the module contents packaged. This is usually what you provide\n  to the client for ergonomics so you don't have to pass multiple arguments per\n  query\n\n#### Advanced\n\n- `serialize` (`t => Raw.t`): this is the opposite of parse.\n  Sometimes you need to convert the ReasonML representation of the response back\n  into the raw JSON representation. Usually this is used within the GraphQL\n  client for things like updating the internal cache.\n- `serializeVariables` (`t_variables => Js.Json.t`): Convert the\n  variables (a record) to a Js.Json.t representation as an alternative to the\n  labeled function\n- `makeInputObject{YourInputObject}` - a labeled function to create\n  `YourInputObject`: This is helpful when you have an input object with many\n  optional values (works exactly the same as makeVariables)\n\n### Types\n\n- `t`: the parsed response of the query\n- `Raw.t`: the unparsed response. This is basically the exact shape of the raw\n  response before it is parsed into more ergonomic ReasonML types like `option`\n  instead of `Js.Json.t`, variants etc.\n- `t_variables`: the variables of the query or mutation\n\nGraphQL objects, variables and input objects are typed as records for `t`,\n`Raw.t` and `t_variables`. The types are named according to the hierarchy. Each\nstep in the hierarchy is split using an underscore. So the type of the user\nobject in the query above is `t_user` if there would be a field that contained\nfriends of the user it would be called `t_user_friends`.\n\n## Alternative ways of using `%graphql`\n\nWhen using GraphQL like this:\n\n```reason\nmodule UserQuery = [%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|}];\n```\n\nIt will have the same effect as the result above. However you can now rename the\nquery module.\n\nYou can also do this:\n\n```reason\nmodule UserQueries = {\n  [%graphql {|\n    query UserQuery {\n      user {\n        id\n        role\n      }\n    }\n  |}];\n};\n```\n\nThis will create a parent module (the query now will be:\n`UserQueries.UserQuery`)\n\nYou can define multiple operations or fragments within a single GraphQL extension\npoint.\n\nIf you do not want to put the query contents in a module, but to be in effect\n\"opened\" in the current module you can use the `inline` option:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      role\n    }\n  }\n|};\n{inline: true}\n];\n```\n\n## Reuse\n\nRecords in Reason are nominally typed. Even if a records contains exactly the\nsame fields as another record, it will be seen as a different type, and they are\nnot compatible. That means that if you want to create an `createAvatar` function\nfor a `User`, you'd be able to accept for instance `UserQuery.t_user` as an\nargument. That's all great, but what if you have another query where you also\nwould like to create an avatar. In most cases Fragments are the solution here.\n\n### Fragments\n\nWith fragments you can define reusable pieces that can be shared between\nqueries. You can define a fragment in the following way\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery {\n    user {\n      id\n      role\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThis generates the module `Avatar_User` as the fragment. The `createAvatar`\ncan now accept `Avatar_User.t` which include all the fields of the fragment.\n\nHow to we get this from the query? When you use the spread operator with the\nmodule name, an extra field is created on the `t_user` record with the name\n`avatar_User` (same as the fragment module name but with a lowercase first\nletter). This is the value that has the type `Avatar_User.t` containing all the\nnecessary fields.\n\nIf you want to change the default name of the fragment you\ncan use a GraphQL alias (`avatarFragment: ...AvatarUser`).\n\nWhen there is just the fragment spread and no other fields on an object, there\nis no special field for the fragment necessary. So if this is the query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      ...Avatar_User\n    }\n  }\n|}]\n```\n\nThen `user` will be of the type `Avatar_User.t`.\n\n#### Variables within fragments\n\nSometimes fragments need to accept variables. Take our previous fragment. If we\nwould like to pass the pixelRatio as a variable as it might vary per device. We\ncan do this as follows:\n\n```reason\n[%graphql {|\n  fragment Avatar_User on User @argumentDefinitions(pixelRatio: {type: \"Float!\"}) {\n    id\n    name\n    smallAvatar: avatar(pixelRatio: 2, width: 60, height: 60) {\n      url\n    }\n  }\n\n  query UserQuery($pixelRatio: Float!) {\n    user {\n      id\n      role\n      ...Avatar_User @arguments(pixelRatio: $pixelRatio)\n    }\n  }\n|}]\n```\n\nTo be able to typecheck these variables and make sure that the types are correct,\nthere are no unused variables or variables that are not defined, we introduce\ntwo directives here `argumentDefinitions` and `arguments`, these are taken from\n[Relay](https://relay.dev/docs/en/fragment-container#argumentdefinitions). But\nthey have nothing to do with the relay client (we just re-use this convention).\n\nNote that you cannot rename variables in the `@arguments` directive so the name\nof the variable and the name of the key must be the same. This is because\nGraphQL PPX does not manipulate variable names and just makes use of the fact\nthat fragments can use variables declared in the query.\n\nThere is a compile error raised if you define variables that are unused. If you\n(temporarily) want to define unused variables you can prepend the variable name\nwith an underscore.\n\n#### `bsAs`\n\nAn ecape hatch for when you don't want GraphQL PPX to create a record type, you\ncan supply one yourself. This also makes reusability possible. We recommend\nfragments however in most cases as they are easier to work, are safer and don't\nrequire defining separate types.\n\n```reason\ntype t_user = {\n  id: string\n  role: string\n}\n\n[%graphql {|\n  query UserQuery {\n    user @bsAs(type: \"t_user\") {\n      id\n      role\n    }\n  }\n|}]\n```\n\n### Custom field decoders\n\nIf you've got a custom scalar, or just want to convert e.g. an integer to a\nstring to properly fit a record type (see above), you can use the `@ppxDecoder`\ndirective to insert a custom function in the decoder:\n\n```reason\nmodule StringHeight = {\n  let parse = (height) => string_of_float(height);\n  let serialize = (height) => float_of_string(height);\n  type t = string;\n}\n\n\nmodule HeroQuery = [%graphql {|\n{\n  hero {\n    name\n    height @ppxDecoder(module: \"StringHeight\")\n    mass\n  }\n}\n|}];\n```\n\nIn this example, `height` will be converted from a float to a string in the\nresult. Using the `module` argument, you can specify any decoder module with\nthe functions `parse`, `serialize` and type `t`.\n\n### Future added values in enums & union variants\n\n`graphql-ppx` will add the polymorphic variant `\\`FutureAddedValue(value)` by default to both enum fields & union variants. This is in accordance to the graphql specification, in order to build robust clients against potentially changing server schemas.\n\n[Lee Byron](https://github.com/leebyron), the co-creator of graphql, says the [following](https://github.com/facebook/relay/issues/2351#issuecomment-368958022) about this topic:\n\n> These are generated as a reminder that GraphQL services often expand in capabilities and may return new enum values. To be future-proof, clients should account for this possibility and do something reasonable to avoid a broken product.\n\nAdding this variant is intentional default behaviour of the ppx, to avoid unintentional production bugs. You have however the option, to specifically opt-out of this behaviour and disable the generation of this additional variant. This could be useful, if you have absolute control over both the client and the server schema and are confident, that they may never be out of sync.\n\nTo opt-out, you can specify the option `future_added_value: false`, either in your `bsconfig.json` (see [config](https://beta.graphql-ppx.com/docs/config)), or directly on your query.\n\nExample:\n\n```reason\nmodule ByConfig = [%graphql\n  {|\n    {\n      someQuery {\n        enumField\n      }\n    }\n|};\n  {future_added_value: false}\n];\n```\n\nThe second way is to use the directive `@ppxOmitFutureValue` directly on your queried field.\n\n```reason\nmodule ByDirective = [%graphql\n  {|\n    {\n      someQuery {\n        enumField @ppxOmitFutureValue\n      }\n    }\n|}\n];\n```\n\n```reason\n// t_someQuery_enumField without config / directive\ntype t_someQuery_enumField = [\n    | `FutureAddedValue(string)\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n// t_someQuery_enumField with config / directive\ntype t_someQuery_enumField = [\n    | `FIRST\n    | `SECOND\n    | `THIRD\n  ];\n```\n\n**Please note:** Decoding the raw query result while having the future value variant disabled, can lead to a `Not_found` exception being thrown if an unexpected result is received.\n\n### Non-union variant conversion\n\nIf you've got an object which in practice behaves like a variant - like `signUp`\nabove, where you _either_ get a user _or_ a list of errors - you can add a\n`@bsVariant` directive to the field to turn it into a polymorphic variant:\n\n```reason\nmodule SignUpQuery = [%graphql\n  {|\nmutation($name: String!, $email: String!, $password: String!) {\n  signUp(email: $email, email: $email, password: $password) @bsVariant {\n    user {\n      name\n    }\n\n    errors {\n      field\n      message\n    }\n  }\n}\n|}\n];\n\nlet _ =\n  Api.sendQuery(\n    ~variables=SignUpQuery.makeVariables(\n      ~name=\"My name\",\n      ~email=\"email@example.com\",\n      ~password=\"secret\",\n      (),\n    ),\n    SignUpQuery.definition\n  )\n  |> Promise.then_(response =>\n       (\n         switch (response.signUp) {\n         | `User(user) => Js.log2(\"Signed up a user with name \", user.name)\n         | `Errors(errors) => Js.log2(\"Errors when signing up: \", errors)\n         }\n       )\n       |> Promise.resolve\n     );\n\n```\n\nThis helps with the fairly common pattern for mutations that can fail with\nuser-readable errors.\n\n## Troubleshooting\n\n### \"Type ... doesn't have any fields\"\n\nSometimes when working with union types you'll get the following error.\n\n```\nFatal error: exception Graphql_ppx_base__Schema.Invalid_type(\"Type IssueTimelineItems doesn't have any fields\")\n```\n\nThis is an example of a query that will result in such error:\n\n```graphql\nnodes {\n  __typename\n  ... on ClosedEvent {\n    closer {\n      __typename\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\nThis is because we allow querying union fields only in certain cases. GraphQL provides the `__typename` field but it's not present in GraphQL introspection query thus `graphql_ppx` doesn't know that this field exists.\nTo fix your query simply remove `__typename`. It's added behinds a scene as an implementation detail and serves us as a way to decide which case to select when parsing your query result.\n\nThis is an example of a correct query:\n\n```graphql\nnodes {\n  ... on ClosedEvent {\n    closer {\n      ... on PullRequest {\n        id\n        milestone { id }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nIf you need to customize certain features of `graphql_ppx` you can provide ppx arguments to do so:\n\n### -apollo-mode\n\nBy default `graphql_ppx` adds `__typename` only to fields on which we need those informations (Unions and Interfaces). If you want to add `__typename` on every object in a query you can specify it by using `-apollo-mode` in `ppx-flags`. It's usefull in case of using `apollo-client` because of it's cache.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-apollo-mode\",]\n],\n```\n\n### -schema\n\nBy default `graphql_ppx` uses `graphql_schema.json` file from your root directory. You can override it by providing `-schema` argument in `ppx-flags` to overriding it.\n\n```json\n\"ppx-flags\": [\n  [\"@baransu/graphql_ppx_re/ppx\", \"-schema ../graphql_schema.json\"]\n],\n```\n\n# Query specific configuration\n\nIf you want to use multiple schemas in your project it can be provided as a secondary config argument in your graphql ppx definition.\n\n```reason\nmodule MyQuery = [%graphql\n  {|\n    query pokemon($id: String, $name: String) {\n      pokemon(name: $name, id: $id) {\n        id\n        name\n      }\n    }\n  |};\n  {schema: \"pokedex_schema.json\"}\n];\n```\n\nThis will use the `pokedex_schema.json` instead of using the default `graphql_schema.json` file.\n\nThis opens up the possibility to use multiple different GraphQL APIs in the same project.\n\n**Note** the path to your file is based on where you run `bsb`. In this case `pokedex_schema.json` is a sibling to `node_modules`.\n\n# Supported platforms\n\n`graphql_ppx` somes with prebuild binaries for `linux-x64`, `darwin-x64` and `win-x64`. If you need support for other platform, please open an issue.\n\n# Contributing\n\n## Developing\n\n```\nnpm install -g esy@latest\nesy install\nesy build\n```\n\n## Running tests\n\n### BuckleScript\n\n```\ncd tests_bucklescript\nnpm test\n```\n\n### Native\n\nFor native run:\n\n```\nesy dune runtest -f\n```\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-619d0df.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-M6e52dmVvb/Ti9q9nsocXrC6YItuY2BvjMYcoLvhvps/lsur0G40U2ens+7tB6MquSjgu/U60DwkRehvF08gvw==","shasum":"09a9cfdccf4a126dcdf017126224bf2cc2b9ca76","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-619d0df.0.tgz","fileCount":410,"unpackedSize":63159742,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe20VxCRA9TVsSAnZWagAAlXEP/jqyNwH+YoLoHrNM9vmn\nT/d7E5pvox1J0OA5VvxkduerJLsXNp3tIPSYKF6D7Q2rfs+/hge+1S9CiDSZ\nzHUTDaQgBZkcBSWLWPF3sCeSTy5leaxssE6NA+8+GhtivXsRhZDsdd91aI/S\nF6t0hzKaOb6SmGfpQ9kkc32zmMlcxqKghTu1Uv+thcyVhv079mR4uGcVcdmd\nspaQlpB8156pvESpw6Tk3b83jfk5V5Mph11hCx140J3tjM6iJEKjAXuxEc0d\n2cqfSYyiEi62l/jOlkdwQjlOcTk1DtzeSdQDldUzBK3Paj7Utv3+fGFU9zMC\nbLLfjaY+NGV92B8Xd2t+i+G12a0RkZ5TE5oRksyoMCxDtO+MWFTsyt4KRSh3\ny72+1iY9FyGAQymrB48rkcHpKadoHwU11HQIn1q04JnWLXUXq03Y+9Kn518d\nkRV/YdgLbtT1XVp86mAvV8FppjFhgfhq0LxYUOfqrHkNcFgtUIBMtz2HJGwM\nT4HMsg5VNqJ3Z4RshG21YUvo5rqe9l0FpSf5CXds2MyFbgIbGcyoMGs2Ilcc\n5CeHe+QgwKWcs4+0DGGalF61zIWfCTlzyQwrdcOIrezw05Lq4GbzUVCxEbGf\nTPP/JZratLJ7/g94xLUQrygN5W1RGwnd6X4iNIvjzUlEqn4hMc6aawO4j5Pb\n+/I4\r\n=+L4X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEPnrSXldKG3efxjzKMF53xTnvwvUnzxC3Nsf3bwhsXOAiEA2xAvGAzNzaJP371bJvsoQIY6ojTgT4FSMQ54PjaKVdU="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-619d0df.0_1591428465084_0.7130070522683367"},"_hasShrinkwrap":false},"1.0.0-76f0afd.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-76f0afd.0","description":"graphql-ppx rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"76f0afd8f907387227b8bba72032d42ebcf40c06","readme":"> This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md)\n\n<p align=\"center\">\n    <img width=\"200\" src=\"https://beta.graphql-ppx.com/img/logo.svg\" alt=\"Logo\">\n  \t<br><br>\n    Typesafe GraphQL operations and fragments in ReasonML\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/reasonml-community/graphql_ppx/actions\">\n    <img src=\"https://github.com/reasonml-community/graphql_ppx/workflows/graphql_ppx%20pipeline/badge.svg\" alt=\"Build Status\" />\n  </a>\n  <a href=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\">\n    <img src=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\" alt=\"npm version\" />\n  </a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#documentation\">Documentation</a> •\n  <a href=\"#features\">Features</a> •\n  <a href=\"#installation\">Installation</a> •\n  <a href=\"#usage\">Usage</a> •\n  <a href=\"#roadmap\">Roadmap</a> •\n  <a href=\"#contributing\">Contributing</a> •\n  <a href=\"#license\">License</a> •\n  <a href=\"#acknowledgements\">Acknowledgements</a>\n</p>\n\n## Documentation\n\n[Go to the official documentation](https://beta.graphql-ppx.com)\n\n## Features\n\n- Language level GraphQL primitives\n\n- Building block for GraphQL clients\n\n- 100% type safe\n\n## Installation\n\n### Schema\n\n`graphql-ppx` needs your graphql schema to be available in the form of a\n`graphql_schema.json` file.\n\nThe easiest way to add this to your project is using an\n[introspection query](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. You can do this using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\nWith `ENDPOINT_URL` being the URL of your GraphQL endpoint.\n\n### Cache\n\n`graphql-ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're using a version control\nsystem, you don't need to check it in.\n\nThe next pages will provide further installation instructions whether you are\nusing `graphql-ppx` with Bucklescript or using Reason Native.\n\n### Bucklescript\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re@next --dev\n# or\nnpm install @baransu/graphql_ppx_re@next  --saveDev\n```\n\nSecond, add it to `ppx-flags` and `bs-dependencies` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"],\n\"bs-dependencies\": [\"@baransu/graphql_ppx_re\"]\n```\n\n### Native\n\n#### Caution!\n\nThe Bucklescript version of `graphql-ppx` was almost completely rewritten for the\n1.0 release, with many improvements and changes. This documentation will focus\non the API of the bucklescript version. This means that most of the examples\nwon't apply for the Reason Native version. Please take a look at the\n[old documentation](https://github.com/reasonml-community/graphql_ppx/tree/v0.7.1).\nAt the same time we welcome contributions to modernize the Reason Native version\nof `graphql-ppx`\n:::\n\nYou need to provide the following dependency in your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nMake your first query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      name\n    }\n  }\n|}];\n```\n\n[Open getting started in the docs](https://beta.graphql-ppx/docs/getting-started)\n\n## Roadmap\n\nSee our [development board](https://github.com/reasonml-community/graphql_ppx/projects/1) for a list of selected features and issues.\n\n## Contributing\n\nWe'd love your help improving `graphql-ppx`!\n\nTake a look at our [Contributing Guide](https://beta.graphql-ppx.com/docs/contributing) to get started.\n\n## License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for more information.\n\n## Acknowledgements\n\nThanks to everyone who [contributed](https://github.com/reasonml-community/graphql_ppx/graphs/contributors) to `graphql-ppx`!\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-76f0afd.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ub9Wus1x9oHZb5FPiOTFlC+m8+mIazwqTkVOLA2XkBt6zqhTi2AVNv4LgfIPp/x3IuLQGJs2j7oyK8pfD5XHOg==","shasum":"38043a21620ce9cf0ef2d4005512e6212ac42191","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-76f0afd.0.tgz","fileCount":415,"unpackedSize":63166754,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe3JWWCRA9TVsSAnZWagAAzOMQAJvQnC1JlZN0R+lUo2CF\n7vAtfhhQfWjGuhNwWRo9ydnvTYwCUM7zkZZlLMnD0+rfB2Sx5dXxNbj0klyN\nLxPoWHQAB6CtbklWUohpc9xt32MsB40uMUB6ys/juDGlddKHOS0yC1tHkVx/\nkCGcnHMZh54vpEU2BODeJ8z9So6D72mf7lVGCc3QyvyPLFvqaBuq2RQDFuxL\nW4/8OT3yD3wGf+2wm7NErneEsCN3GR7mskhr15riJVSDxH6usfso9+/aXhe7\nHRY5x8lwdoi+eETP1q5CqdCAB4eIgHegpqHXFOTOPQ8UdBkEoaWFlyxMOMso\n5kAmoE4orMc8WKJX0OlcxynlccyVdN+KhsG4cAya+Uu7uf2cZn0pIM2fiLn7\nMhNA6LC5uSXRLbdH9FktO9NI/4VfonYAXwYzfOg8ZqQ19178BFgcffFOKbDr\naoygR+DhCRLbA7WNpRK+g2Ap8c/DSe+vNyS2Qxp1qnshtyGhuM3rKaYXhxVb\nqN//xpzIcM7LsghELsew2RnpvKV4HUL01vv1mOpLqUwUkwtsLpgXz3ov0E61\nk1n2IP150sn5clAPiht58DUs0V+h8D24RZ7yeKrvziDT0oNc+sKmKzUVuvrs\ndbsw0Jkjwlw5EpOYAxjYtdrrcLWCY00o0B4VXbsyqoCZFP8v5WwMYohGgKgY\n4+dI\r\n=M6yf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDna+wnBEYhiqZxU5gTchtEUGxoBkAOsOT/w3dB57uLHwIgaoifJj6pp6g9+CzbdxsrJ4JK/8pzHe7IUkIR7aYZyXU="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-76f0afd.0_1591514517121_0.23878826499246308"},"_hasShrinkwrap":false},"1.0.0-40813dc.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-40813dc.0","description":"graphql-ppx rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"40813dc038f7b54d5e897964f4116d6708016153","readme":"> This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md)\n\n<p align=\"center\">\n    <img width=\"200\" src=\"https://beta.graphql-ppx.com/img/logo.svg\" alt=\"Logo\">\n  \t<br><br>\n    Typesafe GraphQL operations and fragments in ReasonML\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/reasonml-community/graphql_ppx/actions\">\n    <img src=\"https://github.com/reasonml-community/graphql_ppx/workflows/graphql_ppx%20pipeline/badge.svg\" alt=\"Build Status\" />\n  </a>\n  <a href=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\">\n    <img src=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\" alt=\"npm version\" />\n  </a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#documentation\">Documentation</a> •\n  <a href=\"#features\">Features</a> •\n  <a href=\"#installation\">Installation</a> •\n  <a href=\"#usage\">Usage</a> •\n  <a href=\"#roadmap\">Roadmap</a> •\n  <a href=\"#contributing\">Contributing</a> •\n  <a href=\"#license\">License</a> •\n  <a href=\"#acknowledgements\">Acknowledgements</a>\n</p>\n\n## Documentation\n\n[Go to the official documentation](https://beta.graphql-ppx.com)\n\n## Features\n\n- Language level GraphQL primitives\n\n- Building block for GraphQL clients\n\n- 100% type safe\n\n## Installation\n\n### Schema\n\n`graphql-ppx` needs your graphql schema to be available in the form of a\n`graphql_schema.json` file.\n\nThe easiest way to add this to your project is using an\n[introspection query](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. You can do this using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\nWith `ENDPOINT_URL` being the URL of your GraphQL endpoint.\n\n### Cache\n\n`graphql-ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're using a version control\nsystem, you don't need to check it in.\n\nThe next pages will provide further installation instructions whether you are\nusing `graphql-ppx` with Bucklescript or using Reason Native.\n\n### Bucklescript\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re@next --dev\n# or\nnpm install @baransu/graphql_ppx_re@next  --saveDev\n```\n\nSecond, add it to `ppx-flags` and `bs-dependencies` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"],\n\"bs-dependencies\": [\"@baransu/graphql_ppx_re\"]\n```\n\n### Native\n\n#### Caution!\n\nThe Bucklescript version of `graphql-ppx` was almost completely rewritten for the\n1.0 release, with many improvements and changes. This documentation will focus\non the API of the bucklescript version. This means that most of the examples\nwon't apply for the Reason Native version. Please take a look at the\n[old documentation](https://github.com/reasonml-community/graphql_ppx/tree/v0.7.1).\nAt the same time we welcome contributions to modernize the Reason Native version\nof `graphql-ppx`\n:::\n\nYou need to provide the following dependency in your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nMake your first query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      name\n    }\n  }\n|}];\n```\n\n[Open getting started in the docs](https://beta.graphql-ppx/docs/getting-started)\n\n## Roadmap\n\nSee our [development board](https://github.com/reasonml-community/graphql_ppx/projects/1) for a list of selected features and issues.\n\n## Contributing\n\nWe'd love your help improving `graphql-ppx`!\n\nTake a look at our [Contributing Guide](https://beta.graphql-ppx.com/docs/contributing) to get started.\n\n## License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for more information.\n\n## Acknowledgements\n\nThanks to everyone who [contributed](https://github.com/reasonml-community/graphql_ppx/graphs/contributors) to `graphql-ppx`!\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-40813dc.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-zq/FbGGIpfN3nS28TyB+W1/Kk+5XZzeswc8QXpi10stvk78X8+mPhqa8NDtk1zuxPmeOr7//AgIZnIHYdrRz3Q==","shasum":"14b49262b0c9b84fe008129478a9fe05c2cee381","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-40813dc.0.tgz","fileCount":415,"unpackedSize":63166754,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe3JdKCRA9TVsSAnZWagAAjPwQAJcYLBrkm+BqILjw3d6c\n+mlxEsJ0SzAld+M6S6g3MClNH5g31BnLr2qH1Bmw6yx6aEPwcH+mOSX0rb9R\n0LszqbbW9bBiEYbyjnuBS6Dq72kBugsQpSXjCjkxD5pU3aX4mPoJCoaOCoEX\nSgJ7iZI8muCJDJcdxWKZew61TNf0vCCo0e3mBhhCHOjQsU85PIQmWuIvVTJu\njWauTWHkcd+VdqNpmoummb5eJKHUr/whmgEmJVzr04ySwJ5+TqC62bwd3AZv\nEGHL9ELE3XI9ToD7paTzdzL0gKciqoHHnlt940GdPYbwUljrNVi1CnyDgQIm\nFDaBhZspsD8ugp+CwdIsfn1fN4bLyZe84iYUYYTjONwz6fP91/CVtnGI0k+1\nc16cik7c4hwNL6EGpEoVGB/SZFat8+YnGX7Ojhsvq5t67EHBYAHVbHlCVmIU\naahlXxoecMAJIA7KW1DbT0M7Go2cB/9PVN8FpFQ8npcn1Z/TNOugUuFdzwXM\nTvyZqyhZoYySRogpo58dUqfEAuRcpEz/7jdbSd5DoqTs9cwTaKuhzreXS8KR\n6M+pVSko2dcJXccYsCQzGc1mP15B60IkZFCgtZhgDhlrHGj2OhoJCuyUFesT\n9dul7HUfgZHmU+x76wFuD++b23GyTdrmBSd1HfUk4adbujykoAcyHYMtfERw\n7Bu0\r\n=Nz+L\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEn0sNM4r29Jw/WUVn/+29yJX7XJkxJWbUAnbtLc7au8AiAYWNd7CVkLoHdO96W/Nt3lO5JoFZztHgFt5ezujETgcw=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-40813dc.0_1591514953193_0.7364543127772754"},"_hasShrinkwrap":false},"1.0.0-beta.10":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-beta.10","description":"graphql-ppx rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"082fb4df8784e72c195c641b44058cb22ac4a94e","readme":"> This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md)\n\n<p align=\"center\">\n    <img width=\"200\" src=\"https://beta.graphql-ppx.com/img/logo.svg\" alt=\"Logo\">\n  \t<br><br>\n    Typesafe GraphQL operations and fragments in ReasonML\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/reasonml-community/graphql_ppx/actions\">\n    <img src=\"https://github.com/reasonml-community/graphql_ppx/workflows/graphql_ppx%20pipeline/badge.svg\" alt=\"Build Status\" />\n  </a>\n  <a href=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\">\n    <img src=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\" alt=\"npm version\" />\n  </a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#documentation\">Documentation</a> •\n  <a href=\"#features\">Features</a> •\n  <a href=\"#installation\">Installation</a> •\n  <a href=\"#usage\">Usage</a> •\n  <a href=\"#roadmap\">Roadmap</a> •\n  <a href=\"#contributing\">Contributing</a> •\n  <a href=\"#license\">License</a> •\n  <a href=\"#acknowledgements\">Acknowledgements</a>\n</p>\n\n## Documentation\n\n[Go to the official documentation](https://beta.graphql-ppx.com)\n\n## Features\n\n- Language level GraphQL primitives\n\n- Building block for GraphQL clients\n\n- 100% type safe\n\n## Installation\n\n### Schema\n\n`graphql-ppx` needs your graphql schema to be available in the form of a\n`graphql_schema.json` file.\n\nThe easiest way to add this to your project is using an\n[introspection query](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. You can do this using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\nWith `ENDPOINT_URL` being the URL of your GraphQL endpoint.\n\n### Cache\n\n`graphql-ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're using a version control\nsystem, you don't need to check it in.\n\nThe next pages will provide further installation instructions whether you are\nusing `graphql-ppx` with Bucklescript or using Reason Native.\n\n### Bucklescript\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re@next --dev\n# or\nnpm install @baransu/graphql_ppx_re@next  --saveDev\n```\n\nSecond, add it to `ppx-flags` and `bs-dependencies` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"],\n\"bs-dependencies\": [\"@baransu/graphql_ppx_re\"]\n```\n\n### Native\n\n#### Caution!\n\nThe Bucklescript version of `graphql-ppx` was almost completely rewritten for the\n1.0 release, with many improvements and changes. This documentation will focus\non the API of the bucklescript version. This means that most of the examples\nwon't apply for the Reason Native version. Please take a look at the\n[old documentation](https://github.com/reasonml-community/graphql_ppx/tree/v0.7.1).\nAt the same time we welcome contributions to modernize the Reason Native version\nof `graphql-ppx`\n:::\n\nYou need to provide the following dependency in your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nMake your first query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      name\n    }\n  }\n|}];\n```\n\n[Open getting started in the docs](https://beta.graphql-ppx/docs/getting-started)\n\n## Roadmap\n\nSee our [development board](https://github.com/reasonml-community/graphql_ppx/projects/1) for a list of selected features and issues.\n\n## Contributing\n\nWe'd love your help improving `graphql-ppx`!\n\nTake a look at our [Contributing Guide](https://beta.graphql-ppx.com/docs/contributing) to get started.\n\n## License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for more information.\n\n## Acknowledgements\n\nThanks to everyone who [contributed](https://github.com/reasonml-community/graphql_ppx/graphs/contributors) to `graphql-ppx`!\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-beta.10","_nodeVersion":"12.18.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-NRSF7A7zkhhnvb+iIixJnNUKUy9JZw/6bs/Pog6ltt91R/nvBq6GolT9aOdmVBRjtryz8kf9jdDnDO1RHoDXdQ==","shasum":"af39c6b387a2d7b6a3d58819637be037e41dd1bd","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-beta.10.tgz","fileCount":415,"unpackedSize":63166752,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe5elFCRA9TVsSAnZWagAAHYUP/3VdVesapqs2D/zPGaGM\nUlh0lxxGSusIstbs7C7Zt0IeFLHyJ2m5ogD6aztMyP2i9iJQmZlT0oVQxZAX\nocBuEca4WI3L5bLpqQD2qr+gtzOsgMirpq3livRPC0biLdgPlw9QoPaqa3IU\nahrPoqfaAXr9Htw00uRqgtwr+IP2gQ3pSm/oFqGvXxAfMWf7VRxF4tc0tsMv\nQ2dbly30Utxdx70Aeni8k7ZsaOWgBO9a557t28Ue/OU5JWulJ5FMFNqifzTa\n6lfa1qfUYAv97c2e/Kr6ozcpUHLQIKa5yUUquzqZugbUDAKgjVv6zUbYiAFK\nI00Hl2TFGhbo7m7NCt2zdwpYZSzWvkPjbiHpyXMTv/fppudbuzYKkp3t8x+5\nGkjg+/9gPECJ/0CJeaQvj3vdluz0NCI+uTiDXLPjZ/kfl55kly/PzpvGf9GD\nc8gHYaya9CDKR96nG27HG0W91H/kx+4KgTzOjeTGiFjbyznNen6cZwLGwcBG\nAgdEQ+vp3RbHiFO7zdeEHtu60aHOgIefby4KEY0MUinUCtquA9l4v37bhgmz\nNcctkH7uttqcdrpZeaUEkvQ7AQPQMNiJhJviJP5oylCLEktuRvtO0PMBau8G\nMnufRW2N4ra6EbBf/jZgXisorV0wa7Ar5ztZpqVwhlUuP8gaoadLlLiydHrm\nurvH\r\n=kcxa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC5kwaiGX37WyOcmyuUJzMaMq9y4Em7GC2j9buUGPPV3AiBfTZ0Q4o3agXMzQphveW+to8IaX9HArY08jCU/R/1kGA=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-beta.10_1592125764664_0.9209351588825507"},"_hasShrinkwrap":false},"1.0.0-082fb4d.0":{"name":"@baransu/graphql_ppx_re","version":"1.0.0-082fb4d.0","description":"graphql-ppx rewriter for Bucklescript/ReasonML","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"contributors":[{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},{"name":"Jaap Frölich","email":"jfrolich@gmail.com"}],"license":"MIT","scripts":{"postinstall":"node ./copyPlatformBinaryInPlace.js"},"publishConfig":{"access":"public"},"dependencies":{"bs-platform":"^7.3.2"},"gitHead":"082fb4df8784e72c195c641b44058cb22ac4a94e","readme":"> This is README for the upcoming 1.0 release. It's available via \"@baransu/graphql_ppx@next\", contains breaking changes and may not work. If you're using 0.x version please check [README from master branch](https://github.com/reasonml-community/graphql_ppx/blob/master/README.md)\n\n<p align=\"center\">\n    <img width=\"200\" src=\"https://beta.graphql-ppx.com/img/logo.svg\" alt=\"Logo\">\n  \t<br><br>\n    Typesafe GraphQL operations and fragments in ReasonML\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/reasonml-community/graphql_ppx/actions\">\n    <img src=\"https://github.com/reasonml-community/graphql_ppx/workflows/graphql_ppx%20pipeline/badge.svg\" alt=\"Build Status\" />\n  </a>\n  <a href=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\">\n    <img src=\"https://badge.fury.io/js/%40baransu%2Fgraphql_ppx_re.svg\" alt=\"npm version\" />\n  </a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#documentation\">Documentation</a> •\n  <a href=\"#features\">Features</a> •\n  <a href=\"#installation\">Installation</a> •\n  <a href=\"#usage\">Usage</a> •\n  <a href=\"#roadmap\">Roadmap</a> •\n  <a href=\"#contributing\">Contributing</a> •\n  <a href=\"#license\">License</a> •\n  <a href=\"#acknowledgements\">Acknowledgements</a>\n</p>\n\n## Documentation\n\n[Go to the official documentation](https://beta.graphql-ppx.com)\n\n## Features\n\n- Language level GraphQL primitives\n\n- Building block for GraphQL clients\n\n- 100% type safe\n\n## Installation\n\n### Schema\n\n`graphql-ppx` needs your graphql schema to be available in the form of a\n`graphql_schema.json` file.\n\nThe easiest way to add this to your project is using an\n[introspection query](https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js)\nto your backend. You can do this using `get-graphql-schema`:\n\n```sh\nnpx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json\n```\n\nWith `ENDPOINT_URL` being the URL of your GraphQL endpoint.\n\n### Cache\n\n`graphql-ppx` will generate a `.graphql_ppx_cache` folder alongside your JSON\nschema to optimize parsing performance. If you're using a version control\nsystem, you don't need to check it in.\n\nThe next pages will provide further installation instructions whether you are\nusing `graphql-ppx` with Bucklescript or using Reason Native.\n\n### Bucklescript\n\nFirst, add it to you dependencies using `npm` or `yarn`:\n\n```sh\nyarn add @baransu/graphql_ppx_re@next --dev\n# or\nnpm install @baransu/graphql_ppx_re@next  --saveDev\n```\n\nSecond, add it to `ppx-flags` and `bs-dependencies` in your `bsconfig.json`:\n\n```json\n\"ppx-flags\": [\"@baransu/graphql_ppx_re/ppx\"],\n\"bs-dependencies\": [\"@baransu/graphql_ppx_re\"]\n```\n\n### Native\n\n#### Caution!\n\nThe Bucklescript version of `graphql-ppx` was almost completely rewritten for the\n1.0 release, with many improvements and changes. This documentation will focus\non the API of the bucklescript version. This means that most of the examples\nwon't apply for the Reason Native version. Please take a look at the\n[old documentation](https://github.com/reasonml-community/graphql_ppx/tree/v0.7.1).\nAt the same time we welcome contributions to modernize the Reason Native version\nof `graphql-ppx`\n:::\n\nYou need to provide the following dependency in your `esy.json` file\n\n```json\n{\n  \"dependencies\": {\n    \"graphql_ppx\": \"*\"\n  },\n  \"resolutions\": {\n    \"graphql_ppx\": \"reasonml-community/graphql_ppx:esy.json#<use latest stable commit from master>\"\n  }\n}\n```\n\nand update your `dune` file:\n\n```\n(preprocess (pps graphql_ppx))\n```\n\n## Usage\n\nMake your first query:\n\n```reason\n[%graphql {|\n  query UserQuery {\n    user {\n      id\n      name\n    }\n  }\n|}];\n```\n\n[Open getting started in the docs](https://beta.graphql-ppx/docs/getting-started)\n\n## Roadmap\n\nSee our [development board](https://github.com/reasonml-community/graphql_ppx/projects/1) for a list of selected features and issues.\n\n## Contributing\n\nWe'd love your help improving `graphql-ppx`!\n\nTake a look at our [Contributing Guide](https://beta.graphql-ppx.com/docs/contributing) to get started.\n\n## License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for more information.\n\n## Acknowledgements\n\nThanks to everyone who [contributed](https://github.com/reasonml-community/graphql_ppx/graphs/contributors) to `graphql-ppx`!\n\nThis project builds upon [mhallin/graphql_ppx](https://github.com/mhallin/graphql_ppx). It wouldn't be possible without\ngreat work of [mhallin/graphql_ppx contributors](https://github.com/mhallin/graphql_ppx/graphs/contributors).\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"homepage":"https://github.com/reasonml-community/graphql_ppx#readme","_id":"@baransu/graphql_ppx_re@1.0.0-082fb4d.0","_nodeVersion":"12.18.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Qh184RaixMhoxsoWyDHin7LwLVkAFO9ct5faw8dGziBxH4Imjgpd+iM3uDWNShwe068MPkPyevspNCffUSTZlQ==","shasum":"1a98b8cb14d671969046f3ef38457781b708d7b4","tarball":"https://registry.npmjs.org/@baransu/graphql_ppx_re/-/graphql_ppx_re-1.0.0-082fb4d.0.tgz","fileCount":415,"unpackedSize":63166754,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe5elSCRA9TVsSAnZWagAAcakP/0CjPeBLhKrVByqeCEzj\nlyT9FJid5ZZVWbmlMNYoMBrwXSD58lEqBA0bB5oRVA1ZPeLDYOLFlO8eYiWZ\ni2BF88p5pWxf10YEkbd7CRPsVbyPCyf3QjXVZ06NmsxAxq8RXxKsQQaKLGbq\nE6Jd/jGPXR7H6TVarXazgq9yr9xhtEabNnGWRXa7jLCTD9amLlQZSElHir9g\nFEPCo8LHv0lDobLtG2hqv7lXMLupXdTyIR+h3w3XbahB/oSgnDv8zJISuTjp\n1tF2jWbXS2DxJ0KJ7SL2Buog7zRRCUeindBSNBzXP0U0lYBBCCM1Dp/mEGhF\nQ7b8z9ckTpFV95JWH+2dLJgTbD6uVK2YJ7XujeoXuPMIZcpxzuXtJWhD4/xP\n2w+T05OSfwEfuuyKKVfzXSDvwgj4verqqi5upM7dIB4W+qjT/vhubJW8WCIk\nhma36XAXDuDPlGGSPHwc1Zrw7+brvWgTwUH/Hs78bh5i8lLI3FGZTmUXqg0M\n+U8P8MSid6fHmPDTKV2FgF2ZYvKMfmmS25EA5lLB5gmYIdNCBmrzi1vGqivZ\nh0/IUVBxZUIEEvF868Q5OyzOFGmV48GKH/RdfpUQxB4OM+0f+QunMDx7nDpS\nM9Q1hjVi2n3a8H/fHcxO+HRT06q+VLDn+/Muy7steXpK7rtVt1dZ3sQ6xo4J\nR5aK\r\n=tpMI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF6PwWe5xW3BiZVnk1+kM2n9ndqNVcaol16q6H/VnS3bAiBb6JBnG2/wE+uPclVHeodazFiuvGtMaFCSvA5DZ8AU9A=="}]},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"_npmUser":{"name":"baransu","email":"tomaszcichocinski@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql_ppx_re_1.0.0-082fb4d.0_1592125777455_0.028043553220748585"},"_hasShrinkwrap":false}},"time":{"created":"2019-08-10T10:07:46.020Z","0.0.9":"2019-08-10T10:07:46.366Z","modified":"2022-04-04T17:43:03.120Z","0.0.11":"2019-08-10T12:02:57.053Z","0.0.12":"2019-08-10T12:31:47.404Z","0.1.0-beta.1":"2019-08-10T12:57:43.075Z","0.1.0-beta.2":"2019-08-10T14:07:58.142Z","0.1.0-beta.3":"2019-09-09T11:21:28.566Z","0.1.0-beta.13":"2019-10-02T12:28:10.634Z","0.1.0-beta.14":"2019-10-04T08:43:18.469Z","0.2.0-beta.1":"2019-10-05T20:26:17.624Z","0.2.0-beta.2":"2019-10-05T21:26:27.178Z","0.2.0":"2019-10-08T10:35:12.100Z","0.3.1":"2019-10-19T10:31:47.758Z","0.3.2":"2019-10-21T21:45:20.166Z","0.3.3":"2019-11-23T15:30:19.919Z","0.3.5":"2019-11-23T17:38:38.155Z","0.4.0":"2019-11-25T19:23:47.206Z","0.4.1":"2019-12-07T13:40:12.302Z","0.4.6":"2019-12-07T14:20:22.920Z","0.4.9":"2020-01-06T17:59:48.916Z","0.5.0-rc2":"2020-01-11T17:21:42.805Z","0.5.0":"2020-01-11T17:29:43.875Z","0.6.0-rc2":"2020-01-23T19:08:30.176Z","0.6.0":"2020-01-23T19:29:50.061Z","0.6.1":"2020-01-23T23:25:17.872Z","0.6.4":"2020-02-18T18:49:23.810Z","0.7.1":"2020-02-24T18:33:46.656Z","1.0.0-beta.1":"2020-03-16T06:56:42.879Z","1.0.0-beta.2":"2020-03-18T08:32:46.079Z","1.0.0-beta.3":"2020-03-28T10:59:09.444Z","1.0.0-beta.4":"2020-03-28T15:43:06.133Z","1.0.0-beta.5":"2020-03-28T16:26:31.447Z","1.0.0-beta.6":"2020-04-13T09:52:52.547Z","1.0.0-9c572d7.0":"2020-04-15T07:09:55.510Z","1.0.0-7ba26b4.0":"2020-04-15T10:58:14.021Z","1.0.0-3175c1b.0":"2020-04-15T11:00:11.130Z","1.0.0-a05c5ee.0":"2020-04-15T11:05:50.530Z","1.0.0-1b6c355.0":"2020-04-18T14:07:15.116Z","1.0.0-c9eb185.0":"2020-04-18T14:30:51.992Z","1.0.0-beta.7":"2020-04-24T13:38:10.076Z","1.0.0-9b6a27e.0":"2020-04-24T16:19:46.819Z","1.0.0-a6ca69c.0":"2020-04-24T16:21:15.841Z","1.0.0-29c4356.0":"2020-04-25T04:05:35.651Z","1.0.0-5cc6072.0":"2020-04-25T04:13:08.816Z","1.0.0-764abee.0":"2020-04-25T04:13:33.185Z","1.0.0-4e4588a.0":"2020-04-25T04:29:05.470Z","1.0.0-30938b3.0":"2020-04-25T04:46:09.744Z","1.0.0-db8afcf.0":"2020-04-25T07:32:26.325Z","1.0.0-9a4cdab.0":"2020-04-25T09:15:13.163Z","1.0.0-0dc3b2e.0":"2020-04-28T05:45:59.515Z","1.0.0-3c47a63.0":"2020-04-28T05:48:52.291Z","1.0.0-8859d7d.0":"2020-04-29T07:34:16.778Z","1.0.0-7d4ca21.0":"2020-04-29T07:56:59.901Z","1.0.0-df4bf4d.0":"2020-04-29T08:11:10.631Z","1.0.0-fc30336.0":"2020-04-30T07:39:45.704Z","1.0.0-3816e31.0":"2020-05-01T03:02:37.537Z","1.0.0-ca361f0.0":"2020-05-01T03:36:52.004Z","1.0.0-cc559c6.0":"2020-05-02T01:38:59.555Z","1.0.0-5a28b89.0":"2020-05-02T03:00:26.859Z","1.0.0-f3a059b.0":"2020-05-02T03:25:10.987Z","1.0.0-70fd977.0":"2020-05-02T04:08:04.124Z","1.0.0-8549e1c.0":"2020-05-02T04:17:29.590Z","1.0.0-28bbd85.0":"2020-05-02T04:41:31.512Z","1.0.0-6cb8491.0":"2020-05-03T10:50:03.632Z","1.0.0-d3088b2.0":"2020-05-03T10:55:39.194Z","1.0.0-e11fb95.0":"2020-05-04T08:15:38.965Z","1.0.0-8b41eb4.0":"2020-05-05T04:13:06.034Z","1.0.0-0a5d763.0":"2020-05-05T05:47:34.590Z","1.0.0-beta.9":"2020-05-05T06:19:21.940Z","1.0.0-6887515.0":"2020-05-07T13:16:58.058Z","1.0.0-5a3b801.0":"2020-05-08T14:56:48.935Z","1.0.0-40d0325.0":"2020-05-08T16:22:01.406Z","1.0.0-b4c3b34.0":"2020-05-09T03:32:12.037Z","1.0.0-3ddadac.0":"2020-05-09T03:34:11.596Z","1.0.0-a334f5c.0":"2020-05-09T06:07:58.352Z","1.0.0-ab34c22.0":"2020-05-09T06:08:17.768Z","1.0.0-7d39c92.0":"2020-05-12T15:38:36.574Z","1.0.0-62b898f.0":"2020-05-12T15:39:59.896Z","1.0.0-098168b.0":"2020-05-13T01:16:32.249Z","1.0.0-b74ef03.0":"2020-05-13T01:43:24.789Z","1.0.0-da905d9.0":"2020-05-13T01:45:58.150Z","1.0.0-eaace91.0":"2020-05-13T01:55:13.126Z","1.0.0-3e84330.0":"2020-05-13T01:56:01.677Z","1.0.0-fc249bf.0":"2020-05-13T01:59:01.995Z","1.0.0-5778171.0":"2020-05-15T06:01:33.199Z","1.0.0-b38e715.0":"2020-05-15T06:15:24.808Z","1.0.0-87a8cd0.0":"2020-05-15T06:18:54.925Z","1.0.0-be935fe.0":"2020-05-15T06:20:53.537Z","1.0.0-60f3105.0":"2020-05-15T06:36:22.967Z","1.0.0-cc4aba6.0":"2020-05-15T10:00:35.487Z","1.0.0-01ee951.0":"2020-05-15T10:00:51.421Z","1.0.0-84750a8.0":"2020-05-15T10:24:14.478Z","1.0.0-047e339.0":"2020-05-15T10:27:33.498Z","1.0.0-d7aa107.0":"2020-05-15T14:27:54.985Z","1.0.0-468c15c.0":"2020-05-23T06:35:41.224Z","1.0.0-d6c9fcb.0":"2020-05-23T06:35:45.947Z","1.0.0-21fb677.0":"2020-05-23T07:34:39.221Z","1.0.0-4ce846f.0":"2020-05-23T07:35:21.986Z","1.0.0-fabc034.0":"2020-05-23T08:04:04.410Z","1.0.0-03f3dfd.0":"2020-05-23T08:12:38.596Z","1.0.0-aa8412e.0":"2020-06-05T07:58:25.175Z","1.0.0-115f639.0":"2020-06-05T10:19:21.002Z","1.0.0-d3c1771.0":"2020-06-05T10:19:43.112Z","1.0.0-23baaef.0":"2020-06-06T04:25:39.231Z","1.0.0-619d0df.0":"2020-06-06T07:27:45.620Z","1.0.0-76f0afd.0":"2020-06-07T07:21:57.658Z","1.0.0-40813dc.0":"2020-06-07T07:29:13.649Z","1.0.0-beta.10":"2020-06-14T09:09:25.127Z","1.0.0-082fb4d.0":"2020-06-14T09:09:37.888Z"},"maintainers":[{"name":"baransu","email":"tomaszcichocinski@gmail.com"}],"description":"GraphQL PPX rewriter for Bucklescript/ReasonML","homepage":"https://github.com/reasonml-community/graphql_ppx#readme","repository":{"type":"git","url":"git+https://github.com/reasonml-community/graphql_ppx.git"},"author":{"name":"Tomasz Cichocinski","email":"tomaszcichocinski@gmail.com"},"bugs":{"url":"https://github.com/reasonml-community/graphql_ppx/issues"},"license":"MIT","readme":"","readmeFilename":""}