{"_id":"@davidmwhynot/ra-data-prisma-backend","name":"@davidmwhynot/ra-data-prisma-backend","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@davidmwhynot/ra-data-prisma-backend","version":"1.0.0","description":"> TODO: description","author":{"name":"Marco Wettstein","email":"maw@panter.ch"},"contributors":[{"name":"David Whynot","email":"davidmwhynot@gmail.com"}],"homepage":"","license":"ISC","main":"lib/index.js","module":"lib-es/index.js","directories":{"lib":"lib","test":"__tests__"},"publishConfig":{"access":"public"},"scripts":{"test":"echo \"Error: run tests from root\" && exit 1","build":"yarn build:cjs && yarn build:es","build:cjs":"rimraf ./lib && tsc --project tsconfig.json --outDir lib --module commonjs","build:es":"rimraf ./lib-es && tsc --project tsconfig.json"},"dependencies":{"lodash":"^4.17.15","pluralize":"^7.0.0"},"peerDependencies":{"nexus":">=1.0.0"},"devDependencies":{"rimraf":"^3.0.2","typescript":"^4.4.3"},"types":"./lib/index.d.ts","gitHead":"216ba6ad26d3c180e4d9afe63f5b653ca63fdd10","_id":"@davidmwhynot/ra-data-prisma-backend@1.0.0","_nodeVersion":"18.20.4","_npmVersion":"10.7.0","dist":{"integrity":"sha512-mHrwXnMXaaIhxC9LSBSFe5ZC8MgmEFji1AR1CTNTGAM8fdG2Fq9LkjFFUoQchhBtbGc070DJMjSJayAXwC8ezA==","shasum":"56ff90ae5970b85adf359a4bc9f69d6da58d10f4","tarball":"https://registry.npmjs.org/@davidmwhynot/ra-data-prisma-backend/-/ra-data-prisma-backend-1.0.0.tgz","fileCount":34,"unpackedSize":36759,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICJE/pOx2QYH1tXvlJzkOQBzEGltVyBLnwbMYgCUSpJRAiBo2EJpnZlCVQmXxRxhut4va3Tc/CY2HfEor1aRHQ8ArQ=="}]},"_npmUser":{"name":"davidmwhynot","email":"davidmwhynot@gmail.com"},"maintainers":[{"name":"davidmwhynot","email":"davidmwhynot@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ra-data-prisma-backend_1.0.0_1729620212991_0.21866868536768758"},"_hasShrinkwrap":false}},"time":{"created":"2024-10-22T18:03:32.849Z","1.0.0":"2024-10-22T18:03:33.260Z","modified":"2024-10-22T18:03:33.896Z"},"maintainers":[{"name":"davidmwhynot","email":"davidmwhynot@gmail.com"}],"description":"> TODO: description","contributors":[{"name":"David Whynot","email":"davidmwhynot@gmail.com"}],"author":{"name":"Marco Wettstein","email":"maw@panter.ch"},"license":"ISC","readme":"# `@ra-data-prisma/backend`\n\nthis package makes your graphql-nexus api compatible with the dataprovider by exposing all needed Queries and Mutations.\n\n## Usage with @nexus/schema\n\n`yarn add @ra-data-prisma/backend`\n\nmake sure that you use `@nexus/schema` version `^0.15.0` and `nexus-plugin-prisma` version `^0.18.2`.\n\n**important: set `paginationStrategy: \"prisma\"` and `experimentalCRUD: true` as options for nexusPrismaPlugin`**\n\n`addCrudResolvers(modelName, options)` will make your Model compatible with react-admin. It will become a `Resource` to react-admin:\n\n```\n\nimport { addCrudResolvers } from '@ra-data-prisma/backend';\nimport { makeSchema } from \"@nexus/schema\";\nimport { nexusSchemaPrisma } from 'nexus-plugin-prisma/schema'\n\ntype User = objectType({\n  name: \"User\",\n  definition(t) {\n    t.field(\"id\") // be sure to expose id for all entities that you want to dit\n    t.field(\"email\")\n    t.field(\"firstname\")\n    t.field(\"lastname\")\n  }\n})\n\nconst schema = makeSchema({\n  types: [\n    User,\n    addCrudResolvers(\"User\") // 👈 this will expose all required Query's and Mutation's.\n  ],\n  plugins: [\n    nexusSchemaPrisma({\n      experimentalCRUD: true, // required!\n      paginationStrategy: \"prisma\", // required!\n      outputs: {\n        typegen: typegenPath(\"./generated/nexus-prisma.ts\")\n      }\n    })\n  ],\n  typegenAutoConfig: {\n     // ...\n  },\n  outputs: {\n      // ...\n  }\n});\n\n\n```\n\nuse `addCrudResolvers` for every Model that you want to manage in react-admin. Additionaly if you have a relation between two Models, call it for both Models even if you only want to show one in a list\n\n## Enable sort by relation\n\nYou can sort by relations. It's currently a preview feature in prisma: https://www.prisma.io/docs/concepts/components/prisma-client/filtering-and-sorting#sort-by-relation-preview\n\n1. make sure you use a more resent prisma version. notice: nexus-plugin-prisma will complain about incompatibility, but it still works with most versions\n2. its enabled by default now ~enable it in `addCrudResolvers`: `addCrudResolvers(modelName, {enableOrderByRelation: true})`~\n3. in react-admin edit the `<ReferenceField />` for this column:\n\n```\n<ReferenceField\n\n  label=\"<your label>\"\n  source=\"<field>\"\n  reference=\"<resource name of the relation>\"\n  sortBy=\"<field>.<related field>\"\n>\n```\n\ne.g. if you have a list of blog posts each with an author and you want to sort by the author's lastname:\n\n```\n<ReferenceField\n\n  label=\"Author\"\n  source=\"author\"\n  reference=\"User\"\n  sortBy=\"author.lastname\"\n>\n```\n\n## Security\n\nMake sure that you restrict access to these resolvers using [graphql-shield](https://github.com/maticzav/graphql-shield) (@nexus/schema)\n\nthis could look like this (for @nexus/schema)\n\n```\nimport { rule, allow, shield } from \"graphql-shield\";\n\nconst isAdmin = rule({ cache: false })(\n  async (parent, args, { user, prisma }: Context, info) => {\n    if (!user) {\n      return false;\n    }\n\n    return prisma.user\n      .findOne({ where: { id: user.id } })\n      .roles({\n        where: {\n          id: \"admin\"\n        }\n      })\n      .then(roles => roles.length > 0);\n  }\n);\n\n\nconst permissions = shield(\n  {\n    Query: {\n      \"*\": allow,\n      users: isAdmin,\n      user: isAdmin,\n\n    },\n    Mutation: {\n      \"*\": isAdmin,\n        // we highly recommend to whitelist the mutations that should be possible for non-admins\n    }\n  },\n);\n\nexport default new ApolloServer({\n  schema: applyMiddleware(schema, permissions),\n  // ...\n})\n\n\n```\n\n### prefix all queries and mutations\n\nTo make it more obvious which resolvers are for the admin area (and therefore need access control), we recommend to set `aliasPrefix`:\n\n_nexus schema_\n\n```\n\naddCrudResolvers(\"User\", {aliasPrefix: \"admin\"})\n\n```\n\n\\*\\*Make sure that your dataprovider uses the same `aliasPrefix` as well.\n\n### alternative approach\n\nin larger projects it could be a good idea that you simply expose a second graphql-endpoint that contains only the admin-CRUD queries and mutations.\nThe permission handling will then be very simple:\n\n```\nconst permissions = shield(\n  {\n  },\n  {\n      fallbackRule: isAdmin\n  }\n);\n```\n","readmeFilename":"README.md"}