{"_id":"@bkonkle/graft","_rev":"2-1c68488919da492dae00a272bff2771d","name":"@bkonkle/graft","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@bkonkle/graft","version":"1.0.0","description":"A ReasonML solution for type-safe querying against an automatic GraphQL backend","repository":{"type":"git","url":"git+ssh://git@github.com/bkonkle/graft.git"},"author":{"name":"Brandon Konkle","email":"brandon@konkle.us","url":"http://konkle.us"},"license":"BSD-2-Clause","keywords":["reasonml","graphql","express"],"scripts":{"build":"yarn build.re","build.re":"bsb -make-world","build.re.clean":"bsb -clean-world","build.re.watch":"yarn build.re -w","precommit":"lint-staged","test.watch":"NODE_ENV=test jest --watch","test":"NODE_ENV=test jest"},"dependencies":{"apollo-errors":"^1.9.0","apollo-server-express":"^1.1.0","body-parser":"^1.18.3","chalk":"^2.4.1","cors":"^2.8.4","dotenv":"^6.0.0","express":"^4.16.3","express-promise-router":"^3.0.3","graphql":"0.11.7","graphql-tag":"^2.9.2","graphql-tools":"^3.0.5","graphql-type-json":"^0.2.1","moment":"^2.22.2","morgan":"^1.9.0","parse-database-url":"^0.3.0"},"devDependencies":{"@playlyfe/gql":"^2.6.0","bs-abstract":"^0.16.0","bs-chalk":"^0.2.1","bs-express":"^0.8.0","bs-moment":"^0.3.0","bs-node-debug":"^0.2.0","bs-platform":"4.0.1","bs-promise-router":"^0.2.0","concurrently":"^3.6.1","dotenv-cli":"^1.4.0","husky":"^0.14.3","identity-obj-proxy":"^3.0.0","lint-staged":"^7.2.0","reason-apollo":"^0.12.0","reason-react":"^0.5.3"},"resolutions":{"graphql":"0.11.7"},"lint-staged":{"src/**/*.re":["refmt --in-place","git add"]},"gitHead":"a62c4f611e3924b529b70c7e14cd35d0b8fdff00","bugs":{"url":"https://github.com/bkonkle/graft/issues"},"homepage":"https://github.com/bkonkle/graft#readme","_id":"@bkonkle/graft@1.0.0","_npmVersion":"6.3.0","_nodeVersion":"10.7.0","_npmUser":{"name":"bkonkle","email":"brandon@ecliptic.io"},"dist":{"integrity":"sha512-SoqgIFTABF+YguCNbJXQgOwRPYf/1/h9lcpEird1zHtRdT23BVHozulXWS4C7pO61syKMi375Hg51WevwogZ2w==","shasum":"f1d0ba71401d1def07ba854b306fa858729652e3","tarball":"https://registry.npmjs.org/@bkonkle/graft/-/graft-1.0.0.tgz","fileCount":32,"unpackedSize":135949,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbg0oVCRA9TVsSAnZWagAAvqIQAKTVhdoSVNfFeMaAbiCQ\nfctY+fDOXIGQNOvKvzfcbRHUZQqDvmiAPTZnzn6npKAM1GQJssJkNsi4cah+\nTcSyd/uvF5lM9pc0g/sy03Il+YrwLLaaG1goKplaKYfjwdnkPYQoGvlNVGSH\nCEebZxRP0RpwiQM0QputTGCwussHbdEQfVls/GCaqVhUfd9B6u5b7h2nx22/\nYuwaR3m7OeGRyqT4JpLYeG7Yi96RUROMdtS/qD3l/yWPy07kOy+U9AjXzbMX\not0RAUBytJJx9YuPtSprjsSafX6WblnvNI5Qr+lv7baBcesnYPe/BNv45sj/\nUps1kwguEvIOZRtNHHGXVY9HQZvPHOnJui6GGKirkHwB6KCY61c9boH/nSl3\nDK4+XrMuyTLrWbpJfMq06YINjBCmCW/91y8gycJyM8mPeESx/LAqRGONoLL4\nr0FZ9NSJmMk9uKHb/Fg4CBzjqmg2cbdiDXYMvksnWmMZcyCnnj23owYqz2ie\n3n5gd2puflz9pXQSLLyAUHBE0x8rRgb2cHnS7NF7psqZzL7eWgG096BOHhkH\nQcCHM3Ibiaf9cXPqTppes+MRGG4ZTbsP99sYhtC5CuDZWIHs5XViXvJ3XXYJ\nM6GzB8zbRTvCx7lo2v4vSZPaus8j0PpZWSCihU3brg6T3GVFKtpy0smO91Jg\nYPrr\r\n=hlUk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAK8lonpRPZxD8MTd0xtBWjp8BB4N4AwK0OHx73x892QIgbU7GI4Z7hvW1Hn+kbb65oSRMKa+ZOorwl+FejSthnEg="}]},"maintainers":[{"name":"bkonkle","email":"brandon@ecliptic.io"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graft_1.0.0_1535330837044_0.17647678954106527"},"_hasShrinkwrap":false},"1.1.0":{"name":"@bkonkle/graft","version":"1.1.0","description":"A ReasonML solution for type-safe querying against an automatic GraphQL backend","repository":{"type":"git","url":"git+ssh://git@github.com/bkonkle/graft.git"},"author":{"name":"Brandon Konkle","email":"brandon@konkle.us","url":"http://konkle.us"},"license":"BSD-2-Clause","keywords":["reasonml","graphql","express"],"scripts":{"build":"yarn build.re","build.re":"bsb -make-world","build.re.clean":"bsb -clean-world","build.re.watch":"yarn build.re -w","precommit":"lint-staged","test.watch":"NODE_ENV=test jest --watch","test":"NODE_ENV=test jest"},"dependencies":{"apollo-errors":"^1.9.0","apollo-server-express":"^1.1.0","body-parser":"^1.18.3","chalk":"^2.4.1","cors":"^2.8.4","dotenv":"^6.0.0","express":"^4.16.3","express-promise-router":"^3.0.3","graphql":"0.11.7","graphql-tag":"^2.9.2","graphql-tools":"^3.0.5","graphql-type-json":"^0.2.1","moment":"^2.22.2","morgan":"^1.9.0","parse-database-url":"^0.3.0","postgraphile":"^4.0.0-rc.4","ramda":"^0.25.0"},"devDependencies":{"@playlyfe/gql":"^2.6.0","bs-abstract":"^0.16.0","bs-chalk":"^0.2.1","bs-express":"^0.8.0","bs-moment":"^0.3.0","bs-node-debug":"^0.2.0","bs-platform":"4.0.1","bs-promise-router":"^0.2.0","concurrently":"^3.6.1","dotenv-cli":"^1.4.0","husky":"^0.14.3","identity-obj-proxy":"^3.0.0","lint-staged":"^7.2.0","reason-apollo":"^0.12.0","reason-react":"^0.5.3"},"resolutions":{"graphql":"0.11.7"},"lint-staged":{"src/**/*.re":["refmt --in-place","git add"]},"gitHead":"15c3b782757f6e3afcd95393c839c74c611ed66b","bugs":{"url":"https://github.com/bkonkle/graft/issues"},"homepage":"https://github.com/bkonkle/graft#readme","_id":"@bkonkle/graft@1.1.0","_npmVersion":"6.3.0","_nodeVersion":"10.7.0","_npmUser":{"name":"bkonkle","email":"brandon@ecliptic.io"},"dist":{"integrity":"sha512-gkeAoEJi4ZtgrKo5oUsA9gMAIltd0lzswX/RHqSPsyVWYeiw8PKkkP0RnT0f0K7NrDB0oft17b3twpdHmjR9tw==","shasum":"cb0253af40a2e879bd0746d999247bae54ec28ff","tarball":"https://registry.npmjs.org/@bkonkle/graft/-/graft-1.1.0.tgz","fileCount":46,"unpackedSize":323768,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbg1snCRA9TVsSAnZWagAALZsP/RBHZtCoE4uLBBvAzC16\nHGrsNVdJOcnUV04XvKOxCCU/ZG0cBCnCaOvOi87QNJkY4zD722kVqc8F2xOd\nhdt0B+WFPc3Gmv0x+b/wo+Fzy68xcWVqeC0sKfplYVtWiaQwfTFOKrOlXuy1\n7ttJmdAhBpLnCVtA3caAcOUCaxDXDOuuyDtiX5IADsdiRLEmasT7VZAHF1Uw\n2ioHpjKpL8XO0d8fLOBS8VZI2bgQMGPJIuakA75v8YBl7FVuEGT8V0rJjGg2\nUzBie2s4fmO2cZI2Czr1PpX2sxCMf45MAZcHjzQPQ7DZqh55fKR8vhtWkKvP\nd5M+0Viii34XCMZrkc2ujcHBsn4m1yHVBKi6t7jZFkzFlq9K0Uo9IVrQZ7jA\nI7hRBk1wEe2ONeIpPP/Be6iD1jPodX5B94W9AJnUtegnQjcMC1nKDW/SK6L/\nkwLNiRSdfhdC15NYeBt5PlUIWSzuHWZOsb2PGkP6/TY2W098XjPUg97KQu0P\nW51DeKqQ9RWlM4edN2PToitSbBiQOd0tY7z7gbTI9jyMV67s+bFhYZWBzalu\nSeS3lOSlXC03WYUBMV7C6ChjUPd9Ji7su5kHskGuz59d/gPJaLB8p44wZbQo\n4Vfr7/2+Bf/QaagZ8/OIX9seR7pZXHW7lmyUh1uOP5Lm762NErZNSb29+iA5\nsgDl\r\n=ViTt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZWiwBbIunMtaIYoUvPmr7Zo8+jgN2CCA8QgjjE90sXQIgDSU/43hehfeyTOJdSt1YRq/sIrI/2jJERCHuoRdUXpo="}]},"maintainers":[{"name":"bkonkle","email":"brandon@ecliptic.io"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graft_1.1.0_1535335206684_0.4099596001827175"},"_hasShrinkwrap":false}},"time":{"created":"2018-08-27T00:47:16.793Z","1.0.0":"2018-08-27T00:47:17.097Z","modified":"2022-04-04T19:18:47.020Z","1.1.0":"2018-08-27T02:00:06.833Z"},"maintainers":[{"name":"bkonkle","email":"brandon@ecliptic.io"}],"description":"A ReasonML solution for type-safe querying against an automatic GraphQL backend","homepage":"https://github.com/bkonkle/graft#readme","keywords":["reasonml","graphql","express"],"repository":{"type":"git","url":"git+ssh://git@github.com/bkonkle/graft.git"},"author":{"name":"Brandon Konkle","email":"brandon@konkle.us","url":"http://konkle.us"},"bugs":{"url":"https://github.com/bkonkle/graft/issues"},"license":"BSD-2-Clause","readme":"# Graft\n\nA [ReasonML][reason] solution for type-safe querying against an automatic GraphQL backend.\n\nGraft helps you set up a [Postgraphile][postgraphile] backend based on PostgreSQL, Express, and Apollo, and then connect to it using ReasonML on the front end. An example client implementation will be included using [reason-react][reason-react] and [reason-apollo][reason-apollo].\n\n## Setup\n\n### API\n\nTo set up a simple API follow the [tag-monster-api](examples/tag-monster-api) example to quickly bootstrap a PostgreSQL database and introspect the schema to create an automatic GraphQL interface.\n\nBring your own ORM or query builder. The example above uses Knex, with a simple [initial migration](examples/tag-monster-api/migrations/001_initial.js). Follow the instructions in the [README](examples/tag-monster-api/README.md) to set up a root user and build the schema.\n\nNext, set up an application-specific config file like [this example](examples/tag-monster-api/src/Config.re).\n\nFrom there, you can throw together a quick server init script like [this example](examples/tag-monster-api/src/Server.re) that uses `Graft.Server.make()` to start an Express server.\n\n### React Client\n\nTo connect to your brand new API from React, create a new ReasonML module in your React application to serve as your API Client. For more information on setting up ReasonML, take a look at the [reason-react][reason-react] docs.\n\n```sh\n$ yarn add --dev @bkonkle/graft\n```\n\n**bsconfig.json**:\n\n```json\n{\n  \"bs-dependencies\": [\"reason-react\", \"reason-apollo\"],\n  \"ppx-flags\": [\"graphql_ppx/ppx\"]\n}\n```\n\n**src/data/ApiClient.re**:\n\n```reasonml\nlet client =\n  Graft.Client.make(\n    ~uri=Config.Api.endpoint,\n    ~getSession=Graft.Browser.Session.get,\n    ~connectToDevTools=Config.Env.isDev ? true : false,\n    (),\n  );\n```\n\nNow, you can start querying with [reason-apollo][reason-apollo]!\n\n```reasonml\nopen Graft.Client;\n\nmodule GetTag = [%graphql\n  {|\n    query GetTag($id: UUID!) {\n      tagById(id: $id) {\n        id\n        name\n        slug\n      }\n    }\n  |}\n];\n\nlet getTag =\n  (. id) => ApiClient.client |> query(~request=GetTag.make(~id, ()));\n\n/**\n * Plain JS interface\n */\nlet default = {\"getTag\": getTag};\n```\n\nThis exposes a default export with a \"getTag\" property that allows plain JavaScript modules to use the `getTag()` function to fire queries. The return value is a standard Apollo Client promise.\n\nNotice that this is not exclusive to React in any way. It's currently un-tested, but it should be possible to use with other libraries as well.\n\n## Development\n\nThe core of the application is an Express server with some middleware:\n\n- [express-promise-router](https://www.npmjs.com/package/express-promise-router)\n- [body-parser](https://github.com/expressjs/body-parser)\n- [cors](https://github.com/expressjs/cors)\n\nInstall dependencies with [Yarn](http://yarnpkg.com):\n\n    $ yarn\n\nThis should install the ReasonML and BuckleScript platform to compile the code to JavaScript.\n\n[reason]: https://reasonml.github.io/\n[reason-react]: https://reasonml.github.io/reason-react/\n[reason-apollo]: https://github.com/apollographql/reason-apollo/\n[postgraphile]: https://www.graphile.org/\n","readmeFilename":"README.md"}