npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

graffiti-mongoose-hotfix

v6.0.15

Published

Mongoose adapter for graffiti (Node.js GraphQL ORM)

Downloads

5

Readme

graffiti Mongoose

npm version CircleCI bitHound Overall Score Known Vulnerabilities

Mongoose (MongoDB) adapter for GraphQL.

graffiti-mongoose generates GraphQL types and schemas from your existing mongoose models, that's how simple it is. The generated schema is compatible with Relay.

For quick jump check out the Usage section.

Install

npm install graphql @risingstack/graffiti-mongoose  --save

Example

Check out the /example folder.

cd graffiti-mongoose
npm install # install dependencies in the main folder
cd example
npm install # install dependencies in the example folder
npm start # run the example application and open your browser: http://localhost:8080

Usage

This adapter is written in ES6 and ES7 with Babel but it's published as transpiled ES5 JavaScript code to npm, which means you don't need ES7 support in your application to run it.

Example queries can be found in the example folder.

usual mongoose model(s)
import mongoose from 'mongoose';

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    // field description
    description: 'the full name of the user'
  },
  hiddenField: {
    type: Date,
    default: Date.now,
    // the field is hidden, not available in GraphQL
    hidden: true
  },
  age: {
    type: Number,
    indexed: true
  },
  friends: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  }]
});

const User = mongoose.model('User', UserSchema);
export default User;
graffiti-mongoose
import {getSchema} from '@risingstack/graffiti-mongoose';
import graphql from 'graphql';
import User from './User';

const options = {
  mutation: false, // mutation fields can be disabled
  allowMongoIDMutation: false // mutation of mongo _id can be enabled
};
const schema = getSchema([User], options);

const query = `{
    users(age: 28) {
      name
      friends(first: 2) {
        edges {
          cursor
          node {
            name
            age
          }
        }
        pageInfo {
          startCursor
          endCursor
          hasPreviousPage
          hasNextPage
        }
      }
    }
  }`;

graphql(schema, query)
  .then((result) => {
    console.log(result);
  });

Supported mongoose types

  • Number
  • String
  • Boolean
  • Date
  • [Number]
  • [String]
  • [Boolean]
  • [Date]
  • ObjectId with ref (reference to other document, populate)

Supported query types

  • query
    • singular: for example user
    • plural: for example users
    • node: takes a single argument, a unique !ID, and returns a Node
    • viewer: singular and plural queries as fields

Supported query arguments

  • indexed fields
  • "id" on singular type
  • array of "id"s on plural type

Which means, you are able to filter like below, if the age is indexed in your mongoose model:

users(age: 19) {}
user(id: "mongoId1") {}
user(id: "relayId") {}
users(id: ["mongoId", "mongoId2"]) {}
users(id: ["relayId1", "relayId2"]) {}

Supported mutation types

  • mutation
    • addX: for example addUser
    • updateX: for example updateUser
    • deleteX: for example deleteUser

Supported mutation arguments

  • scalar types
  • arrays
  • references

Examples:

mutation addX {
  addUser(input: {name: "X", age: 11, clientMutationId: "1"}) {
    changedUserEdge {
      node {
        id
        name
      }
    }
  }
}
mutation updateX {
  updateUser(input: {id: "id=", age: 10, clientMutationId: "2"}) {
    changedUser {
      id
      name
      age
    }
  }
}
mutation deleteX {
  deleteUser(input: {id: "id=", clientMutationId: "3"}) {
    ok
  }
}

Resolve hooks

You can specify pre- and post-resolve hooks on fields in order to manipulate arguments and data passed in to the database resolve function, and returned by the GraphQL resolve function.

You can add hooks to type fields and query fields (singular & plural queries, mutations) too. By passing arguments to the next function, you can modify the parameters of the next hook or the return value of the resolve function.

Examples:

  • Query, mutation hooks (viewer, singular, plural, mutation)
const hooks = {
  viewer: {
    pre: (next, root, args, request) => {
      // authorize the logged in user based on the request
      authorize(request);
      next();
    },
    post: (next, value) => {
      console.log(value);
      next();
    }
  },
  // singular: {
  //   pre: (next, root, args, context) => next(),
  //   post: (next, value, args, context) => next()
  // },
  // plural: {
  //   pre: (next, root, args, context) => next(),
  //   post: (next, value, args, context) => next()
  // },
  // mutation: {
  //   pre: (next, args, context) => next(),
  //   post: (next, value, args, context) => next()
  // }
};
const schema = getSchema([User], {hooks});
  • Field hooks
const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    hooks: {
      pre: (next, root, args, request) => {
        // authorize the logged in user based on the request
        // throws error if the user has no right to request the user names
        authorize(request);
        next();
      },
      // manipulate response
      post: [
        (next, name) => next(`${name} first hook`),
        (next, name) => next(`${name} & second hook`)
      ]
    }
  }
});
query UsersQuery {
  viewer {
    users(first: 1) {
      edges {
        node {
          name
        }
      }
    }
  }
}
{
  "data": {
    "viewer": {
      "users": {
        "edges": [
          {
            "node": {
              "name": "User0 first hook & second hook"
            }
          }
        ]
      }
    }
  }
}

Test

npm test

Contributing

Please read the CONTRIBUTING.md file.

License

MIT