{"id":13475037,"url":"https://github.com/graphql-compose/graphql-compose","last_synced_at":"2025-05-13T17:10:35.519Z","repository":{"id":9031134,"uuid":"60592864","full_name":"graphql-compose/graphql-compose","owner":"graphql-compose","description":"Toolkit for generating complex GraphQL Schemas on Node.js","archived":false,"fork":false,"pushed_at":"2025-01-11T15:31:11.000Z","size":5053,"stargazers_count":1213,"open_issues_count":85,"forks_count":75,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-24T01:57:16.439Z","etag":null,"topics":["graphql","graphql-compose","hacktoberfest","schema","schema-builder","toolkit"],"latest_commit_sha":null,"homepage":"https://graphql-compose.github.io/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/graphql-compose.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["nodkz"],"patreon":null,"open_collective":"graphql-compose","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2016-06-07T07:43:40.000Z","updated_at":"2025-03-28T04:18:40.000Z","dependencies_parsed_at":"2024-05-13T17:25:12.547Z","dependency_job_id":"844cbb96-8d60-40c8-b28e-b31ca8398d5c","html_url":"https://github.com/graphql-compose/graphql-compose","commit_stats":{"total_commits":853,"total_committers":38,"mean_commits":22.44736842105263,"dds":0.3927315357561547,"last_synced_commit":"5606c4f53955f0ffcebbd276b9d87e1597a91055"},"previous_names":["nodkz/graphql-compose"],"tags_count":260,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphql-compose","download_url":"https://codeload.github.com/graphql-compose/graphql-compose/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252107195,"owners_count":21695837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-compose","hacktoberfest","schema","schema-builder","toolkit"],"created_at":"2024-07-31T16:01:16.883Z","updated_at":"2025-05-13T17:10:30.501Z","avatar_url":"https://github.com/graphql-compose.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/graphql-compose/graphql-compose/master/docs/logo.png\" width=\"200\" /\u003e\u003c/p\u003e\n\n# graphql-compose\n\n[![](https://img.shields.io/npm/v/graphql-compose.svg)](https://www.npmjs.com/package/graphql-compose)\n[![codecov coverage](https://img.shields.io/codecov/c/github/graphql-compose/graphql-compose.svg)](https://codecov.io/github/graphql-compose/graphql-compose)\n[![Travis](https://img.shields.io/travis/graphql-compose/graphql-compose.svg?maxAge=2592000)](https://travis-ci.org/graphql-compose/graphql-compose)\n[![npm](https://img.shields.io/npm/dt/graphql-compose.svg)](http://www.npmtrends.com/graphql-compose)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n![TypeScript compatible](https://img.shields.io/badge/typescript-compatible-brightgreen.svg)\n[![Backers on Open Collective](https://opencollective.com/graphql-compose/backers/badge.svg)](#backers)\n[![Sponsors on Open Collective](https://opencollective.com/graphql-compose/sponsors/badge.svg)](#sponsors)\n\n**`graphql-compose`** – provides a type registry with a bunch of methods for programmatic schema construction. It allows not only to extend types but also remove fields, interfaces, args. **If you want to write your graphql schema generator – `graphql-compose` is a good instrument for you.**\n\n* provides methods for editing GraphQL output/input types (add/remove fields/args/interfaces)\n* introduces ```Resolver's``` – the named graphql fieldConfigs, which can be used for finding, updating, removing records\n* provides an easy way for creating relations between types via ```Resolver's```\n* provides converter from `OutputType` to `InputType`\n* provides `projection` parser from AST\n* provides `GraphQL schema language` for defining simple types\n* adds additional types `Date`, `Json`\n\n## And a little bit more\n\n**`graphql-compose-[plugin]`** – are _declarative generators/plugins_ built on top of `graphql-compose`, which take some ORMs, schema definitions and create GraphQL Models from them or modify existing GraphQL Types.\n\n### Type generators built on top `graphql-compose`\n\n* [graphql-compose-json](https://github.com/graphql-compose/graphql-compose-json) - generates GraphQL type from JSON (a good helper for wrapping REST APIs)\n* [graphql-compose-mongoose](https://github.com/graphql-compose/graphql-compose-mongoose) - generates GraphQL types from mongoose (MongoDB models) with Resolvers.\n* [graphql-compose-elasticsearch](https://github.com/graphql-compose/graphql-compose-elasticsearch) - generates GraphQL types from elastic mappings; ElasticSearch REST API proxy via GraphQL.\n* [graphql-compose-aws](https://github.com/graphql-compose/graphql-compose-aws) - expose AWS Cloud API via GraphQL\n\n### Utility plugins:\n\n* [graphql-compose-relay](https://github.com/graphql-compose/graphql-compose-relay) - reassemble GraphQL types with `Relay` specific things, like `Node` type and interface, `globalId`, `clientMutationId`.\n* [graphql-compose-connection](https://github.com/graphql-compose/graphql-compose-connection) - generates `connection` Resolver from `findMany` and `count` Resolvers.\n* [graphql-compose-dataloader](https://github.com/stoffern/graphql-compose-dataloader) - adds DataLoader to graphql-composer resolvers.\n\n## Documentation\n\n[graphql-compose.github.io](https://graphql-compose.github.io/)\n\n## Live Demos\n\n* [graphql-compose.herokuapp.com](https://graphql-compose.herokuapp.com/) - Live demo of GraphQL Server (9 models, 14 files, ~750 LOC)\n* [nodkz.github.io/relay-northwind](https://nodkz.github.io/relay-northwind) - Live demo of Relay client working with the server above (8 crazy pages, 47 files, ~3000 LOC)\n\n## Examples\n\nPlease follow [Quick Start Guide](https://graphql-compose.github.io/docs/intro/quick-start.html) for the complete example.\n\nHere is just a demo of ambiguity ways of types definitions:\n\n```js\nimport { schemaComposer} from 'graphql-compose';\n\n// You may use SDL format for type definition\nconst CityTC = schemaComposer.createObjectTC(`\n  type City {\n    code: String!\n    name: String!\n    population: Number\n    countryCode: String\n    tz: String\n  }\n`);\n\n// Define type via Config object\nconst CountryTC = schemaComposer.createObjectTC({\n  name: 'Country',\n  fields: {\n    title: 'String',\n    geo: `type LonLat { lon: Float, lat: Float }`,\n    hoisting: {\n      type: () =\u003e AnotherTC,\n      description: `\n        You may wrap type in thunk for solving\n        hoisting problems when two types cross reference\n        each other.\n      `,\n    }\n  }\n});\n\n// Or via declarative methods define some additional fields\nCityTC.addFields({\n  country: CountryTC, // some another Type\n  ucName: { // standard GraphQL like field definition\n    type: GraphQLString,\n    resolve: (source) =\u003e source.name.toUpperCase(),\n  },\n  currentLocalTime: { // extended GraphQL Compose field definition\n    type: 'Date',\n    resolve: (source) =\u003e moment().tz(source.tz).format(),\n    projection: { tz: true }, // load `tz` from database, when requested only `localTime` field\n  },\n  counter: 'Int', // shortening for only type definition for field\n  complex: `type ComplexType {\n    subField1: String\n    subField2: Float\n    subField3: Boolean\n    subField4: ID\n    subField5: JSON\n    subField6: Date\n  }`,\n  list0: {\n    type: '[String]',\n    description: 'Array of strings',\n  },\n  list1: '[String]',\n  list2: ['String'],\n  list3: [new GraphQLOutputType(...)],\n  list4: [`type Complex2Type { f1: Float, f2: Int }`],\n});\n\n// Add resolver method\nCityTC.addResolver({\n  kind: 'query',\n  name: 'findMany',\n  args: {\n    filter: `input CityFilterInput {\n      code: String!\n    }`,\n    limit: {\n      type: 'Int',\n      defaultValue: 20,\n    },\n    skip: 'Int',\n    // ... other args if needed\n  },\n  type: [CityTC], // array of cities\n  resolve: async ({ args, context }) =\u003e {\n    return context.someCityDB\n      .findMany(args.filter)\n      .limit(args.limit)\n      .skip(args.skip);\n  },\n});\n\n// Remove `tz` field from schema\nCityTC.removeField('tz');\n\n// Add description to field\nCityTC.extendField('name', {\n  description: 'City name',\n});\n\nschemaComposer.Query.addFields({\n  cities: CityTC.getResolver('findMany'),\n  currentTime: {\n    type: 'Date',\n    resolve: () =\u003e Date.now(),\n  },\n});\n\nschemaComposer.Mutation.addFields({\n  createCity: CityTC.getResolver('createOne'),\n  updateCity: CityTC.getResolver('updateById'),\n  ...adminAccess({\n    removeCity: CityTC.getResolver('removeById'),\n  }),\n});\n\nfunction adminAccess(resolvers) {\n  Object.keys(resolvers).forEach(k =\u003e {\n    resolvers[k] = resolvers[k].wrapResolve(next =\u003e rp =\u003e {\n      // rp = resolveParams = { source, args, context, info }\n      if (!rp.context.isAdmin) {\n        throw new Error('You should be admin, to have access to this action.');\n      }\n      return next(rp);\n    });\n  });\n  return resolvers;\n}\n\n// construct schema which can be passed to express-graphql, apollo-server or graphql-yoga\nexport const schema = schemaComposer.buildSchema();\n```\n\n## Contributors\n\nThis project exists thanks to all the people who contribute.\n\u003ca href=\"graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/graphql-compose#backer)]\n\n\u003ca href=\"https://opencollective.com/graphql-compose#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/graphql-compose#sponsor)]\n\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/graphql-compose/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/graphql-compose/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n\n## License\n\n[MIT](https://github.com/graphql-compose/graphql-compose/blob/master/LICENSE.md)\n","funding_links":["https://github.com/sponsors/nodkz","https://opencollective.com/graphql-compose"],"categories":["TypeScript","Libraries","Implementations","hacktoberfest"],"sub_categories":["JavaScript Libraries","JavaScript/TypeScript"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-compose%2Fgraphql-compose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphql-compose%2Fgraphql-compose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-compose%2Fgraphql-compose/lists"}