├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .husky
└── pre-commit
├── .prettierrc.js
├── .travis.yml
├── LICENSE
├── README.md
├── jest.config.js
├── package.json
├── src
├── diffSchema.js
├── index.js
├── loadSchemaJSON.js
├── renderSchema.js
└── updateSchema.js
├── test
├── __snapshots__
│ └── index.test.js.snap
├── fixtures
│ ├── cover-art-archive.js
│ ├── cover-art-archive.md
│ ├── graphbrainz-updateSchema-initial.md
│ ├── graphbrainz-updateSchema-updated.md
│ ├── graphbrainz-updateSchema.js
│ ├── graphbrainz.graphql
│ ├── graphbrainz.md
│ ├── input-objects.graphql
│ ├── input-objects.md
│ ├── no-toc.md
│ ├── toc-fields.md
│ ├── union-test-2.graphql
│ ├── union-test-2.md
│ ├── union-test.graphql
│ └── union-test.md
└── index.test.js
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | /.nyc_output
2 | /coverage
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['standard', 'prettier'],
3 | env: {
4 | es6: true,
5 | node: true,
6 | jest: true,
7 | },
8 | parserOptions: {
9 | ecmaVersion: 2018,
10 | },
11 | plugins: ['prettier'],
12 | rules: {
13 | 'prettier/prettier': [
14 | 'warn',
15 | {
16 | singleQuote: true,
17 | semi: false,
18 | },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | lint-staged
5 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | proseWrap: "always"
3 | };
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - '10'
5 | - '12'
6 | - '14'
7 | - '15'
8 |
9 | # Use container-based Travis infrastructure.
10 | sudo: false
11 |
12 | branches:
13 | only:
14 | - master
15 | - /^greenkeeper/.*$/
16 |
17 | script:
18 | - yarn test
19 |
20 | after_success:
21 | - yarn run coverage
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016–2018 Brian Beck
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # graphql-markdown
4 |
5 | **The easiest way to document your GraphQL schema.**
6 |
7 | [](https://www.npmjs.com/package/graphql-markdown)
8 |
9 |
10 |
11 | ---
12 |
13 | This package will generate Markdown that beautifully renders your GraphQL schema
14 | in an easily explorable document.
15 |
16 | ```console
17 | $ yarn add graphql-markdown --dev
18 | $ npm install graphql-markdown --save-dev
19 | ```
20 |
21 | **[See an example][example]** generated from the [GraphBrainz][] schema.
22 |
23 | ## Support
24 |
25 | Did this project bring you joy? Want to support updates? Check out
26 | [my GitHub Sponsors page](https://github.com/sponsors/exogen).
27 |
28 | Alternatively…
29 |
30 |
31 |
32 | ## Usage
33 |
34 | ### Command Line API
35 |
36 | Installing the package adds a `graphql-markdown` script via the standard package.json
37 | [`bin`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#bin) field – see
38 | npm’s [Executables](https://docs.npmjs.com/cli/v10/configuring-npm/folders#executables)
39 | documentation to learn where this will be on your system. For local installs,
40 | this is typically `node_modules/.bin`. When referencing the executable in
41 | your package.json’s `scripts`, you may simply call `graphql-markdown`.
42 |
43 | Point the `graphql-markdown` script at a schema and the output will be written
44 | to stdout. You must install `graphql` alongside this package according to the
45 | [compatible versions specified in `peerDependencies`](./package.json).
46 |
47 | The schema may be retrieved from a GraphQL endpoint:
48 |
49 | ```console
50 | $ graphql-markdown http://your-server.com/graphql > schema.md
51 | ```
52 |
53 | …or a module exporting an instance of `GraphQLSchema`:
54 |
55 | ```console
56 | $ graphql-markdown ./path/to/schema.js > schema.md
57 | ```
58 |
59 | …or a file containing GraphQL syntax:
60 |
61 | ```console
62 | $ graphql-markdown ./path/to/schema.graphql > schema.md
63 | ```
64 |
65 | …or a file containing the JSON output of an introspection query:
66 |
67 | ```console
68 | $ graphql-markdown ./path/to/schema.json > schema.md
69 | ```
70 |
71 | If `--update-file` is given, the generated Markdown will be output to the given
72 | file between the `` and
73 | `` comment markers instead of printed to STDOUT. If
74 | the file does not exist, it will be created (and will include the comment
75 | markers for future updates). Use this if you’d like to embed the rendered
76 | Markdown as just one part of a larger document (see also the `--heading-level`
77 | option).
78 |
79 | #### Options
80 |
81 | ```console
82 | $ graphql-markdown --help
83 |
84 | Usage: graphql-markdown [options]
85 |
86 | Output a Markdown document with rendered descriptions and links between types.
87 | The schema may be specified as:
88 |
89 | - a URL to the GraphQL endpoint (the introspection query will be run)
90 | - a GraphQL document containing the schema (.graphql or .gql)
91 | - a JSON document containing the schema (as returned by the introspection query)
92 | - an importable module with the schema as its default export (either an instance
93 | of GraphQLSchema or a JSON object)
94 |
95 | Options:
96 |
97 | --title Change the top heading title (default: 'Schema Types')
98 | --no-title Do not print a default title
99 | --no-toc Do not print table of contents
100 | --toc-fields Expand the table of contents for the listed types
101 | (comma-separated) to link to fields within those types
102 | (e.g. --toc-fields "Query,Mutation,Subscription") or use
103 | the string "*" to link to fields for all types
104 | --prologue Include custom Markdown after the title
105 | --epilogue Include custom Markdown after everything else
106 | --heading-level Heading level to begin at, useful if you are embedding the
107 | output in a document with other sections (default: 1)
108 | --update-file Markdown document to update (between comment markers) or
109 | create (if the file does not exist)
110 | --require If importing the schema from a module, require the specified
111 | module first (useful for e.g. babel-register)
112 | --header Additional header(s) to use in GraphQL request
113 | e.g. --header "Authorization=Bearer ey..."
114 | --version Print version and exit
115 | ```
116 |
117 | ### Node API
118 |
119 | The following functions are exported from the `graphql-markdown` module for
120 | programmatic use.
121 |
122 | #### loadSchemaJSON(schemaPath: string, options: object)
123 |
124 | Given a string pointing to a GraphQL schema (URL, module, or file path), get the
125 | result of the introspection query, suitable for use as input to `renderSchema`.
126 |
127 | #### renderSchema(schema: object, options: object)
128 |
129 | Given a schema JSON object (the output of the introspection query, an object
130 | with a `__schema` property), render the schema to the console or the provided
131 | `printer` function.
132 |
133 | ##### Options
134 |
135 | - **`title`**: The title of the document, defaults to “Schema Types”.
136 | - **`prologue`**: Markdown content to include after the title.
137 | - **`epilogue`**: Markdown content to include after everything else.
138 | - **`printer`**: A function to handle each line of output, defaults to
139 | `console.log`.
140 | - **`skipTableOfContents`**: When set, rendering of "Table of contents" section
141 | is skipped.
142 | - **`tocFieldTypes`**: An array of type names whose table of contents entry will
143 | be expanded to link to individual fields in a nested list. Include the special
144 | name `*` in the array to match all types.
145 | - **`headingLevel`**: The initial level at which to render Markdown headings in
146 | the output, defaults to 1. Use this if you are using `updateSchema` to embed
147 | the output in a larger document with other sections.
148 | - **`unknownTypeURL`**: A string or function to determine the URL for linking to
149 | types that aren’t found in the schema being rendered. This may be the case if
150 | you’re rendering the result of `diffSchema()`, for example. String values will
151 | have `#${type.name.toLowerCase()}` appended, and function values will be
152 | called with the type object for full control.
153 |
154 | #### updateSchema(path: string, schema: object, options: object)
155 |
156 | Given a path to a Markdown document, inject the output of `renderSchema` (with
157 | the given schema and options) into the document between the comment markers
158 | `` and ``. Returns a
159 | Promise.
160 |
161 | If the file does not exist, it will be created. If the document is empty, the
162 | necessary comment markers will automatically be inserted, but if there is
163 | existing content and no comment markers, the Promise will be rejected with an
164 | error.
165 |
166 | #### diffSchema(oldSchema: object, newSchema: object, options: object)
167 |
168 | Given two schema JSON objects (the results of the introspection query on two
169 | schemas), return a new schema JSON object containing only the added or updated
170 | types and fields. You can use this to document a schema update, or to document
171 | the effects of a schema extension (e.g. `extend type` definitions).
172 |
173 | ##### Options
174 |
175 | - **`processTypeDiff`**: A function to add or modify fields on each type that
176 | will be output.
177 |
178 | ## Output
179 |
180 | Output is optimized for display on GitHub, using GitHub Flavored Markdown. Due
181 | to the complexity of the tables in the generated document, much of the table
182 | output is raw HTML (as allowed by Markdown).
183 |
184 | [example]: https://github.com/exogen/graphbrainz/blob/master/docs/types.md
185 | [graphbrainz]: https://github.com/exogen/graphbrainz
186 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | collectCoverageFrom: ['src/**'],
3 | }
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql-markdown",
3 | "version": "7.3.0",
4 | "description": "Generate documentation for your GraphQL schema in Markdown",
5 | "main": "src/index.js",
6 | "bin": "src/index.js",
7 | "repository": "git@github.com:exogen/graphql-markdown.git",
8 | "author": "Brian Beck ",
9 | "license": "MIT",
10 | "engines": {
11 | "node": ">=14.0.0"
12 | },
13 | "files": [
14 | "src",
15 | "yarn.lock"
16 | ],
17 | "scripts": {
18 | "coverage": "cat coverage/lcov.info | coveralls",
19 | "format": "npm run lint:fix || true",
20 | "lint": "eslint .",
21 | "lint:fix": "eslint --fix .",
22 | "prepare": "husky install",
23 | "test": "npm run lint && npm run test:coverage",
24 | "test:coverage": "jest --coverage",
25 | "test:only": "jest"
26 | },
27 | "lint-staged": {
28 | "*.js": [
29 | "eslint --fix"
30 | ]
31 | },
32 | "peerDependencies": {
33 | "graphql": "^14.0.2 || ^15.0.0 || ^16.0.0"
34 | },
35 | "dependencies": {
36 | "deep-diff": "^1.0.2",
37 | "lodash.isplainobject": "^4.0.6",
38 | "minimist": "^1.2.6",
39 | "node-fetch": "^2.0.0",
40 | "resolve-from": "^5.0.0"
41 | },
42 | "devDependencies": {
43 | "coveralls": "^3.1.1",
44 | "eslint": "^8.24.0",
45 | "eslint-config-prettier": "^8.5.0",
46 | "eslint-config-standard": "^17.0.0",
47 | "eslint-plugin-import": "^2.26.0",
48 | "eslint-plugin-n": "^15.3.0",
49 | "eslint-plugin-node": "^11.1.0",
50 | "eslint-plugin-prettier": "^4.2.1",
51 | "eslint-plugin-promise": "^6.0.1",
52 | "eslint-plugin-standard": "^5.0.0",
53 | "graphbrainz": "^8.0.0",
54 | "graphql": "^16.0.0",
55 | "husky": "^8.0.1",
56 | "jest": "^29.1.2",
57 | "lint-staged": "^13.0.3",
58 | "prettier": "^2.7.1",
59 | "tempy": "^1.0.0"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/diffSchema.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const diff = require('deep-diff')
3 |
4 | function toNamedObject(arr, modifier = (obj) => obj) {
5 | if (!arr) {
6 | return {}
7 | }
8 | return arr.reduce((obj, value) => {
9 | obj[value.name] = modifier(value)
10 | return obj
11 | }, {})
12 | }
13 |
14 | function toNamedArray(obj, modifier = (obj) => obj) {
15 | if (!obj) {
16 | return []
17 | }
18 | return Object.entries(obj).map(([key, value]) => {
19 | return modifier(Object.assign({}, value, { name: key }))
20 | })
21 | }
22 |
23 | function toDiffableSchema(schema) {
24 | const types = toNamedObject(schema.__schema.types, (type) => {
25 | if (type.fields) {
26 | type = Object.assign({}, type, {
27 | fields: toNamedObject(type.fields),
28 | })
29 | }
30 | if (type.enumValues) {
31 | type = Object.assign({}, type, {
32 | enumValues: toNamedObject(type.enumValues),
33 | })
34 | }
35 | return type
36 | })
37 |
38 | const directives = toNamedObject(schema.__schema.directives)
39 |
40 | return Object.assign({}, schema, {
41 | __schema: Object.assign({}, schema.__schema, {
42 | types,
43 | directives,
44 | }),
45 | })
46 | }
47 |
48 | function fromDiffableSchema(schema) {
49 | const types = toNamedArray(schema.__schema.types, (type) => {
50 | if (type.fields) {
51 | type = Object.assign({}, type, {
52 | fields: toNamedArray(type.fields),
53 | })
54 | }
55 | if (type.enumValues) {
56 | type = Object.assign({}, type, {
57 | enumValues: toNamedArray(type.enumValues),
58 | })
59 | }
60 | return type
61 | })
62 |
63 | const directives = toNamedArray(schema.__schema.directives)
64 |
65 | return Object.assign({}, schema, {
66 | __schema: Object.assign({}, schema.__schema, {
67 | types,
68 | directives,
69 | }),
70 | })
71 | }
72 |
73 | function diffSchema(oldSchema, newSchema, options = {}) {
74 | const oldDiffableSchema = toDiffableSchema(oldSchema)
75 | const newDiffableSchema = toDiffableSchema(newSchema)
76 | const changes = diff(oldDiffableSchema, newDiffableSchema)
77 | const diffSchema = changes.reduce((schema, change) => {
78 | diff.applyChange(schema, newDiffableSchema, change)
79 | return schema
80 | }, {})
81 | const schema = fromDiffableSchema(diffSchema)
82 | const newTypes = newDiffableSchema.__schema.types
83 | schema.__schema.types = schema.__schema.types.map((type) => {
84 | if (options.processTypeDiff) {
85 | type = options.processTypeDiff(type)
86 | }
87 | type = Object.assign({}, newTypes[type.name], type)
88 | if (type.fields) {
89 | const newFields = newTypes[type.name].fields
90 | type.fields = type.fields.map((field) => newFields[field.name])
91 | }
92 | if (type.enumValues) {
93 | const newEnumValues = newTypes[type.name].enumValues
94 | type.enumValues = type.enumValues.map(
95 | (enumValue) => newEnumValues[enumValue.name]
96 | )
97 | }
98 | return type
99 | })
100 | return schema
101 | }
102 |
103 | module.exports = diffSchema
104 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict'
3 | const parseArgs = require('minimist')
4 | const resolveFrom = require('resolve-from')
5 | const { loadSchemaJSON, schemaToJSON } = require('./loadSchemaJSON')
6 | const renderSchema = require('./renderSchema')
7 | const updateSchema = require('./updateSchema')
8 | const diffSchema = require('./diffSchema')
9 |
10 | function safeExit(code) {
11 | process.on('exit', function () {
12 | process.exit(code)
13 | })
14 | }
15 |
16 | function printHelp(console) {
17 | const name = require('../package.json').name
18 | console.log(`
19 | Usage: ${name} [options]
20 |
21 | Output a Markdown document with rendered descriptions and links between types.
22 | The schema may be specified as:
23 |
24 | - a URL to the GraphQL endpoint (the introspection query will be run)
25 | - a GraphQL document containing the schema (.graphql or .gql)
26 | - a JSON document containing the schema (as returned by the introspection query)
27 | - an importable module with the schema as its default export (either an instance
28 | of GraphQLSchema or a JSON object)
29 |
30 | Options:
31 |
32 | --title Change the top heading title (default: 'Schema Types')
33 | --no-title Do not print a default title
34 | --no-toc Do not print table of contents
35 | --toc-fields Expand the table of contents for the listed types
36 | (comma-separated) to link to fields within those types
37 | (e.g. --toc-fields "Query,Mutation,Subscription") or use
38 | the string "*" to link to fields for all types
39 | --prologue Include custom Markdown after the title
40 | --epilogue Include custom Markdown after everything else
41 | --heading-level Heading level to begin at, useful if you are embedding the
42 | output in a document with other sections (default: 1)
43 | --update-file Markdown document to update (between comment markers) or
44 | create (if the file does not exist)
45 | --require If importing the schema from a module, require the specified
46 | module first (useful for e.g. babel-register)
47 | --header Additional header(s) to use in GraphQL request
48 | e.g. --header "Authorization=Bearer ey..."
49 | --version Print version and exit
50 | `)
51 | }
52 |
53 | function run(
54 | argv = process.argv.slice(2),
55 | { console = global.console, exit = true } = {}
56 | ) {
57 | const args = parseArgs(argv)
58 |
59 | if (args.help) {
60 | printHelp(console)
61 | } else if (args.version) {
62 | console.log(require('../package.json').version)
63 | } else if (args._.length === 1) {
64 | if (args.require) {
65 | const requirePath = resolveFrom('.', args.require)
66 | if (requirePath) {
67 | require(requirePath)
68 | } else {
69 | throw new Error(`Could not resolve --require module: ${args.require}`)
70 | }
71 | }
72 | const schemaPath = args._[0]
73 | const headers = [].concat(args.header || []).reduce((obj, header) => {
74 | const [key, ...value] = String(header).split('=')
75 | obj[key] = value.join('=')
76 | return obj
77 | }, {})
78 | const tocFieldTypes = args['toc-fields']
79 | ? args['toc-fields'].split(',')
80 | : []
81 | const loadOptions = { headers }
82 | loadSchemaJSON(schemaPath, loadOptions).then((schema) => {
83 | const options = {
84 | title: args.title,
85 | skipTitle: false,
86 | prologue: args.prologue,
87 | epilogue: args.epilogue,
88 | skipTableOfContents: args.toc === false,
89 | headingLevel: args['heading-level'],
90 | tocFieldTypes,
91 | }
92 | if (options.title === false) {
93 | options.title = ''
94 | options.skipTitle = true
95 | } else if (Array.isArray(options.title)) {
96 | options.title.forEach((value) => {
97 | if (typeof value === 'string') {
98 | options.title = value
99 | } else if (value === false) {
100 | options.skipTitle = true
101 | }
102 | })
103 | }
104 | const updateFile = args['update-file']
105 | if (updateFile) {
106 | updateSchema(updateFile, schema, options)
107 | .then(() => {
108 | if (exit) {
109 | safeExit(0)
110 | }
111 | })
112 | .catch((err) => {
113 | console.error(err)
114 | if (exit) {
115 | safeExit(1)
116 | }
117 | })
118 | } else {
119 | renderSchema(schema, options)
120 | if (exit) {
121 | safeExit(0)
122 | }
123 | }
124 | })
125 | } else {
126 | printHelp(console)
127 | if (exit) {
128 | safeExit(1)
129 | }
130 | }
131 | }
132 |
133 | module.exports = {
134 | run,
135 | loadSchemaJSON,
136 | schemaToJSON,
137 | renderSchema,
138 | updateSchema,
139 | diffSchema,
140 | }
141 |
142 | if (require.main === module) {
143 | run()
144 | }
145 |
--------------------------------------------------------------------------------
/src/loadSchemaJSON.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const fs = require('fs')
3 | const fetch = require('node-fetch')
4 | const graphql = require('graphql')
5 | const resolveFrom = require('resolve-from')
6 | const isPlainObject = require('lodash.isplainobject')
7 |
8 | const DEFAULT_GRAPHQL = graphql
9 |
10 | function readFile(filename) {
11 | return new Promise((resolve, reject) => {
12 | fs.readFile(filename, 'utf8', (err, data) =>
13 | err ? reject(err) : resolve(data)
14 | )
15 | })
16 | }
17 |
18 | function schemaToJSON(schema, options) {
19 | options = options || {}
20 | const graphql = options.graphql || DEFAULT_GRAPHQL
21 | const source = graphql.getIntrospectionQuery()
22 | return graphql.graphql({ schema, source }).then((result) => {
23 | return result.data
24 | })
25 | }
26 |
27 | function fetchSchemaJSON(url, options) {
28 | options = options || {}
29 | const graphql = options.graphql || DEFAULT_GRAPHQL
30 | return fetch(url, {
31 | method: 'POST',
32 | headers: {
33 | Accept: 'application/json',
34 | 'Content-Type': 'application/json',
35 | ...options.headers,
36 | },
37 | body: JSON.stringify({ query: graphql.getIntrospectionQuery() }),
38 | })
39 | .then((res) => res.json())
40 | .then((result) => result.data)
41 | }
42 |
43 | function parseSchemaGraphQL(filename, options) {
44 | options = options || {}
45 | const graphql = options.graphql || DEFAULT_GRAPHQL
46 | return readFile(filename).then((data) => graphql.buildSchema(data))
47 | }
48 |
49 | async function requireSchema(schemaPath) {
50 | const schemaModule = resolveFrom('.', schemaPath)
51 | if (!schemaModule) {
52 | throw new Error(`Could not resolve schema module: ${schemaPath}`)
53 | }
54 | let schema = require(schemaModule)
55 | if (schema) {
56 | if (schema.default) {
57 | schema = schema.default
58 | }
59 | // Allow modules to export a Promise that resolves to a schema.
60 | schema = await schema
61 | }
62 | // Getting `.default` and resolving a potential Promise may have resulted in
63 | // `schema` not being an object anymore.
64 | if (schema) {
65 | if (!isPlainObject(schema)) {
66 | if (schema instanceof DEFAULT_GRAPHQL.GraphQLSchema) {
67 | return schemaToJSON(schema)
68 | }
69 | const graphqlPath = resolveFrom(schemaModule, 'graphql')
70 | if (!graphqlPath) {
71 | throw new Error(
72 | 'Could not import the `graphql` instance used by the given schema'
73 | )
74 | }
75 | const graphql = require(graphqlPath)
76 | if (schema instanceof graphql.GraphQLSchema) {
77 | return schemaToJSON(schema, { graphql })
78 | }
79 | } else if (schema.queryType) {
80 | return { __schema: schema }
81 | } else if (schema.__schema) {
82 | return schema
83 | } else if (schema.data && schema.data.__schema) {
84 | return schema.data
85 | }
86 | }
87 | throw new Error(
88 | `Schema not found in ${schemaModule} - check that you are exporting ` +
89 | 'an instance of GraphQLSchema or the result of an introspection query'
90 | )
91 | }
92 |
93 | function loadSchemaJSON(schemaPath, loadOptions) {
94 | if (schemaPath.indexOf('://') >= 0) {
95 | return fetchSchemaJSON(schemaPath, loadOptions)
96 | } else if (schemaPath.match(/\.g(raph)?ql$/)) {
97 | return parseSchemaGraphQL(schemaPath, loadOptions).then(schemaToJSON)
98 | }
99 | return requireSchema(schemaPath)
100 | }
101 |
102 | module.exports = { loadSchemaJSON, schemaToJSON }
103 |
--------------------------------------------------------------------------------
/src/renderSchema.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | function sortBy(arr, property) {
3 | arr.sort((a, b) => {
4 | const aValue = a[property]
5 | const bValue = b[property]
6 | if (aValue > bValue) return 1
7 | if (bValue > aValue) return -1
8 | return 0
9 | })
10 | }
11 |
12 | function renderType(type, options) {
13 | if (type.kind === 'NON_NULL') {
14 | return renderType(type.ofType, options) + '!'
15 | }
16 | if (type.kind === 'LIST') {
17 | return `[${renderType(type.ofType, options)}]`
18 | }
19 | const url = options.getTypeURL(type)
20 | return url ? `${type.name}` : type.name
21 | }
22 |
23 | function renderObject(type, options) {
24 | options = options || {}
25 | const skipTitle = options.skipTitle === true
26 | const printer = options.printer || console.log
27 | const headingLevel = options.headingLevel || 1
28 | const getTypeURL = options.getTypeURL
29 | const getFieldURL = options.getFieldURL
30 | const isInputObject = type.kind === 'INPUT_OBJECT'
31 | const isInterface = type.kind === 'INTERFACE'
32 |
33 | if (!skipTitle) {
34 | printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`)
35 | }
36 | if (type.description) {
37 | printer(`${type.description}\n`)
38 | }
39 | printer('')
40 | printer('')
41 | printer('')
42 | if (isInputObject) {
43 | printer('Field | ')
44 | } else {
45 | printer('Field | ')
46 | printer('Argument | ')
47 | }
48 | printer('Type | ')
49 | printer('Description | ')
50 | printer('
')
51 | printer('')
52 | printer('')
53 |
54 | const fields = isInputObject ? type.inputFields : type.fields
55 | fields.forEach((field) => {
56 | const url = getFieldURL(type, field)
57 | const anchor = url && url.split('#')[1]
58 | const fieldNameMarkup = anchor
59 | ? `${field.name}`
60 | : `${field.name}`
61 | printer('')
62 | printer(
63 | `${fieldNameMarkup}${
64 | field.isDeprecated ? ' ⚠️' : ''
65 | } | `
66 | )
67 | printer(
68 | `${renderType(field.type, {
69 | getTypeURL,
70 | getFieldURL,
71 | })} | `
72 | )
73 | if (field.description || field.isDeprecated) {
74 | printer('')
75 | if (field.description) {
76 | printer(`\n${field.description}\n`)
77 | }
78 | if (field.isDeprecated) {
79 | printer(' ⚠️ DEPRECATED ')
80 | if (field.deprecationReason) {
81 | printer('')
82 | printer(`\n${field.deprecationReason}\n`)
83 | printer(' ')
84 | }
85 | }
86 | printer(' | ')
87 | } else {
88 | printer(' | ')
89 | }
90 | printer('
')
91 | if (!isInputObject && field.args.length) {
92 | field.args.forEach((arg, i) => {
93 | printer('')
94 | printer(`${arg.name} | `)
95 | printer(
96 | `${renderType(arg.type, {
97 | getTypeURL,
98 | getFieldURL,
99 | })} | `
100 | )
101 | if (arg.description) {
102 | printer('')
103 | printer(`\n${arg.description}\n`)
104 | printer(' | ')
105 | } else {
106 | printer(' | ')
107 | }
108 | printer('
')
109 | })
110 | }
111 | })
112 | printer('')
113 | printer('
')
114 |
115 | if (isInterface && type.possibleTypes && type.possibleTypes.length) {
116 | printer(
117 | `\n**Possible Types:** ${type.possibleTypes
118 | .map((type) => `[${type.name}](${getTypeURL(type)})`)
119 | .join(', ')}`
120 | )
121 | }
122 | }
123 |
124 | function renderSchema(schema, options) {
125 | options = options || {}
126 | const title = options.title || 'Schema Types'
127 | const skipTitle = options.skipTitle || false
128 | const skipTableOfContents = options.skipTableOfContents || false
129 | const prologue = options.prologue || ''
130 | const epilogue = options.epilogue || ''
131 | const printer = options.printer || console.log
132 | const headingLevel = options.headingLevel || 1
133 | const unknownTypeURL = options.unknownTypeURL
134 | const tocFieldTypes = options.tocFieldTypes || []
135 | const tocFieldAllTypes = tocFieldTypes.includes('*')
136 |
137 | if (schema.__schema) {
138 | schema = schema.__schema
139 | }
140 |
141 | const types = schema.types.filter((type) => !type.name.startsWith('__'))
142 | const typeMap = schema.types.reduce((typeMap, type) => {
143 | return Object.assign(typeMap, { [type.name]: type })
144 | }, {})
145 |
146 | const getTypeURL = (type) => {
147 | const url = `#${type.name.toLowerCase()}`
148 | if (typeMap[type.name]) {
149 | return url
150 | } else if (typeof unknownTypeURL === 'function') {
151 | return unknownTypeURL(type)
152 | } else if (unknownTypeURL) {
153 | return unknownTypeURL + url
154 | }
155 | }
156 |
157 | const getFieldURL = (type, field) => {
158 | const url = getTypeURL(type)
159 | return url && `${url}.${field.name.toLowerCase()}`
160 | }
161 |
162 | const queryType = schema.queryType
163 | const query =
164 | queryType && types.find((type) => type.name === schema.queryType.name)
165 | const mutationType = schema.mutationType
166 | const mutation =
167 | mutationType && types.find((type) => type.name === schema.mutationType.name)
168 | const subscriptionType = schema.subscriptionType
169 | const subscription =
170 | subscriptionType &&
171 | types.find((type) => type.name === schema.subscriptionType.name)
172 |
173 | const objects = types.filter(
174 | (type) =>
175 | type.kind === 'OBJECT' &&
176 | type !== query &&
177 | type !== mutation &&
178 | type !== subscription
179 | )
180 | const inputs = types.filter((type) => type.kind === 'INPUT_OBJECT')
181 | const enums = types.filter((type) => type.kind === 'ENUM')
182 | const scalars = types.filter((type) => type.kind === 'SCALAR')
183 | const interfaces = types.filter((type) => type.kind === 'INTERFACE')
184 | const unions = types.filter((type) => type.kind === 'UNION')
185 |
186 | sortBy(objects, 'name')
187 | sortBy(inputs, 'name')
188 | sortBy(enums, 'name')
189 | sortBy(scalars, 'name')
190 | sortBy(interfaces, 'name')
191 | sortBy(unions, 'name')
192 |
193 | if (!skipTitle) {
194 | printer(`${'#'.repeat(headingLevel)} ${title}\n`)
195 | }
196 |
197 | if (prologue) {
198 | printer(`${prologue}\n`)
199 | }
200 |
201 | if (!skipTableOfContents) {
202 | printer('')
203 | printer(' Table of Contents
\n')
204 | if (query) {
205 | printer(' * [Query](#query)')
206 | if (tocFieldAllTypes || tocFieldTypes.includes(query.name)) {
207 | query.fields.forEach((field) => {
208 | printer(` * [${field.name}](${getFieldURL(query, field)})`)
209 | })
210 | }
211 | }
212 | if (mutation) {
213 | printer(' * [Mutation](#mutation)')
214 | if (tocFieldAllTypes || tocFieldTypes.includes(mutation.name)) {
215 | mutation.fields.forEach((field) => {
216 | printer(` * [${field.name}](${getFieldURL(mutation, field)})`)
217 | })
218 | }
219 | }
220 | if (subscription) {
221 | printer(' * [Subscription](#subscription)')
222 | if (tocFieldAllTypes || tocFieldTypes.includes(subscription.name)) {
223 | subscription.fields.forEach((field) => {
224 | printer(` * [${field.name}](${getFieldURL(subscription, field)})`)
225 | })
226 | }
227 | }
228 | if (objects.length) {
229 | printer(' * [Objects](#objects)')
230 | objects.forEach((type) => {
231 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
232 | if (tocFieldAllTypes || tocFieldTypes.includes(type.name)) {
233 | type.fields.forEach((field) => {
234 | printer(` * [${field.name}](${getFieldURL(type, field)})`)
235 | })
236 | }
237 | })
238 | }
239 | if (inputs.length) {
240 | printer(' * [Inputs](#inputs)')
241 | inputs.forEach((type) => {
242 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
243 | if (tocFieldAllTypes || tocFieldTypes.includes(type.name)) {
244 | type.inputFields.forEach((field) => {
245 | printer(` * [${field.name}](${getFieldURL(type, field)})`)
246 | })
247 | }
248 | })
249 | }
250 | if (enums.length) {
251 | printer(' * [Enums](#enums)')
252 | enums.forEach((type) => {
253 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
254 | })
255 | }
256 | if (scalars.length) {
257 | printer(' * [Scalars](#scalars)')
258 | scalars.forEach((type) => {
259 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
260 | })
261 | }
262 | if (interfaces.length) {
263 | printer(' * [Interfaces](#interfaces)')
264 | interfaces.forEach((type) => {
265 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
266 | if (tocFieldAllTypes || tocFieldTypes.includes(type.name)) {
267 | type.fields.forEach((field) => {
268 | printer(` * [${field.name}](${getFieldURL(type, field)})`)
269 | })
270 | }
271 | })
272 | }
273 | if (unions.length) {
274 | printer(' * [Unions](#unions)')
275 | unions.forEach((type) => {
276 | printer(` * [${type.name}](#${type.name.toLowerCase()})`)
277 | })
278 | }
279 | printer('\n ')
280 | }
281 |
282 | if (query) {
283 | printer(
284 | `\n${'#'.repeat(headingLevel + 1)} Query${
285 | query.name === 'Query' ? '' : ' (' + query.name + ')'
286 | }`
287 | )
288 | renderObject(query, {
289 | skipTitle: true,
290 | headingLevel,
291 | printer,
292 | getTypeURL,
293 | getFieldURL,
294 | })
295 | }
296 |
297 | if (mutation) {
298 | printer(
299 | `\n${'#'.repeat(headingLevel + 1)} Mutation${
300 | mutation.name === 'Mutation' ? '' : ' (' + mutation.name + ')'
301 | }`
302 | )
303 | renderObject(mutation, {
304 | skipTitle: true,
305 | headingLevel,
306 | printer,
307 | getTypeURL,
308 | getFieldURL,
309 | })
310 | }
311 |
312 | if (subscription) {
313 | printer(
314 | `\n${'#'.repeat(headingLevel + 1)} Subscription${
315 | subscription.name === 'Subscription'
316 | ? ''
317 | : ' (' + subscription.name + ')'
318 | }`
319 | )
320 | renderObject(subscription, {
321 | skipTitle: true,
322 | headingLevel,
323 | printer,
324 | getTypeURL,
325 | getFieldURL,
326 | })
327 | }
328 |
329 | if (objects.length) {
330 | printer(`\n${'#'.repeat(headingLevel + 1)} Objects`)
331 | objects.forEach((type) =>
332 | renderObject(type, { headingLevel, printer, getTypeURL, getFieldURL })
333 | )
334 | }
335 |
336 | if (inputs.length) {
337 | printer(`\n${'#'.repeat(headingLevel + 1)} Inputs`)
338 | inputs.forEach((type) =>
339 | renderObject(type, { headingLevel, printer, getTypeURL, getFieldURL })
340 | )
341 | }
342 |
343 | if (enums.length) {
344 | printer(`\n${'#'.repeat(headingLevel + 1)} Enums`)
345 | enums.forEach((type) => {
346 | printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`)
347 | if (type.description) {
348 | printer(`${type.description}\n`)
349 | }
350 | printer('')
351 | printer('')
352 | printer('')
353 | printer('Value | ')
354 | printer('Description | ')
355 | printer('
')
356 | printer('')
357 | printer('')
358 | type.enumValues.forEach((value) => {
359 | printer('')
360 | printer(
361 | `${value.name}${
362 | value.isDeprecated ? ' ⚠️' : ''
363 | } | `
364 | )
365 | if (value.description || value.isDeprecated) {
366 | printer('')
367 | if (value.description) {
368 | printer(`\n${value.description}\n`)
369 | }
370 | if (value.isDeprecated) {
371 | printer(' ⚠️ DEPRECATED ')
372 | if (value.deprecationReason) {
373 | printer('')
374 | printer(`\n${value.deprecationReason}\n`)
375 | printer(' ')
376 | }
377 | }
378 | printer(' | ')
379 | } else {
380 | printer(' | ')
381 | }
382 | printer('
')
383 | })
384 | printer('')
385 | printer('
')
386 | })
387 | }
388 |
389 | if (scalars.length) {
390 | printer(`\n${'#'.repeat(headingLevel + 1)} Scalars\n`)
391 | scalars.forEach((type) => {
392 | printer(`${'#'.repeat(headingLevel + 2)} ${type.name}\n`)
393 | if (type.description) {
394 | printer(`${type.description}\n`)
395 | }
396 | })
397 | }
398 |
399 | if (interfaces.length) {
400 | printer(`\n${'#'.repeat(headingLevel + 1)} Interfaces\n`)
401 | interfaces.forEach((type) =>
402 | renderObject(type, { headingLevel, printer, getTypeURL, getFieldURL })
403 | )
404 | }
405 |
406 | if (unions.length) {
407 | printer(`\n${'#'.repeat(headingLevel + 1)} Unions`)
408 | unions.forEach((type) => {
409 | printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`)
410 | if (type.description) {
411 | printer(`${type.description}\n`)
412 | }
413 | printer('')
414 | printer('')
415 | printer('')
416 | printer('Type | ')
417 | printer('Description | ')
418 | printer('
')
419 | printer('')
420 | printer('')
421 | type.possibleTypes.forEach((objType) => {
422 | const obj = objects.find((o) => objType.name === o.name)
423 | const desc = objType.description || (obj && obj.description)
424 | printer('')
425 | printer(
426 | `${renderType(objType, {
427 | getTypeURL,
428 | getFieldURL,
429 | })} | `
430 | )
431 | if (desc) {
432 | printer('')
433 | printer(`\n${desc}\n`)
434 | printer(' | ')
435 | } else {
436 | printer(' | ')
437 | }
438 | printer('
')
439 | })
440 | printer('')
441 | printer('
')
442 | })
443 | }
444 |
445 | if (epilogue) {
446 | printer(`\n${epilogue}`)
447 | }
448 | }
449 |
450 | module.exports = renderSchema
451 |
--------------------------------------------------------------------------------
/src/updateSchema.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const renderSchema = require('./renderSchema')
3 |
4 | function updateMarkdown(doc, newContent, options = {}) {
5 | const includeMarkers = options.includeMarkers !== false
6 | const startMarker = options.startMarker || ''
7 | const endMarker = options.endMarker || ''
8 | let startIndex = doc.indexOf(startMarker)
9 | let endIndex = doc.lastIndexOf(endMarker)
10 | if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {
11 | if (includeMarkers) {
12 | startIndex += startMarker.length
13 | } else {
14 | endIndex += endMarker.length
15 | }
16 | return doc.slice(0, startIndex) + newContent + doc.slice(endIndex)
17 | } else if (startIndex === -1) {
18 | throw new Error(`Start marker not found: ${startMarker}`)
19 | } else if (endIndex === -1) {
20 | throw new Error(`End marker not found: ${endMarker}`)
21 | } else {
22 | throw new Error('Start marker must precede end marker.')
23 | }
24 | }
25 |
26 | function updateSchema(path, schema, options) {
27 | return new Promise((resolve, reject) => {
28 | fs.readFile(path, 'utf8', (err, doc) => {
29 | if (err) {
30 | if (err.code === 'ENOENT') {
31 | doc = ''
32 | } else {
33 | return reject(err)
34 | }
35 | }
36 | let newContent = ''
37 | const printer = (line) => {
38 | newContent += `${line}\n`
39 | }
40 | renderSchema(schema, Object.assign({}, options, { printer }))
41 | if (!doc.trim()) {
42 | doc = '\n\n'
43 | }
44 | let newDoc = doc
45 | try {
46 | newDoc = updateMarkdown(doc, `\n\n${newContent}\n`)
47 | } catch (err) {
48 | return reject(err)
49 | }
50 | fs.writeFile(path, newDoc, 'utf8', (err) => {
51 | if (err) {
52 | return reject(err)
53 | }
54 | resolve()
55 | })
56 | })
57 | })
58 | }
59 |
60 | module.exports = updateSchema
61 |
--------------------------------------------------------------------------------
/test/__snapshots__/index.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`diffSchema() outputs a JSON schema containing only additions 1`] = `
4 | {
5 | "__schema": {
6 | "directives": [],
7 | "types": [
8 | {
9 | "description": "A [release](https://musicbrainz.org/doc/Release) represents the
10 | unique release (i.e. issuing) of a product on a specific date with specific
11 | release information such as the country, label, barcode, packaging, etc. If you
12 | walk into a store and purchase an album or single, they’re each represented in
13 | MusicBrainz as one release.",
14 | "enumValues": null,
15 | "fields": [
16 | {
17 | "args": [],
18 | "deprecationReason": null,
19 | "description": "An object containing a list and summary of the cover art images that are
20 | present for this release from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).
21 | This field is provided by the Cover Art Archive extension.",
22 | "isDeprecated": false,
23 | "name": "coverArtArchive",
24 | "type": {
25 | "kind": "OBJECT",
26 | "name": "CoverArtArchiveRelease",
27 | "ofType": null,
28 | },
29 | },
30 | ],
31 | "inputFields": null,
32 | "interfaces": [
33 | {
34 | "kind": "INTERFACE",
35 | "name": "Node",
36 | "ofType": null,
37 | },
38 | {
39 | "kind": "INTERFACE",
40 | "name": "Entity",
41 | "ofType": null,
42 | },
43 | ],
44 | "kind": "OBJECT",
45 | "name": "Release",
46 | "possibleTypes": null,
47 | },
48 | {
49 | "description": "A [release group](https://musicbrainz.org/doc/Release_Group) is
50 | used to group several different releases into a single logical entity. Every
51 | release belongs to one, and only one release group.
52 |
53 | Both release groups and releases are “albums” in a general sense, but with an
54 | important difference: a release is something you can buy as media such as a CD
55 | or a vinyl record, while a release group embraces the overall concept of an
56 | album – it doesn’t matter how many CDs or editions/versions it had.",
57 | "enumValues": null,
58 | "fields": [
59 | {
60 | "args": [],
61 | "deprecationReason": null,
62 | "description": "The cover art for a release in the release group, obtained from the
63 | [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive). A
64 | release in the release group will be chosen as representative of the release
65 | group.
66 | This field is provided by the Cover Art Archive extension.",
67 | "isDeprecated": false,
68 | "name": "coverArtArchive",
69 | "type": {
70 | "kind": "OBJECT",
71 | "name": "CoverArtArchiveRelease",
72 | "ofType": null,
73 | },
74 | },
75 | ],
76 | "inputFields": null,
77 | "interfaces": [
78 | {
79 | "kind": "INTERFACE",
80 | "name": "Node",
81 | "ofType": null,
82 | },
83 | {
84 | "kind": "INTERFACE",
85 | "name": "Entity",
86 | "ofType": null,
87 | },
88 | ],
89 | "kind": "OBJECT",
90 | "name": "ReleaseGroup",
91 | "possibleTypes": null,
92 | },
93 | {
94 | "description": "An object containing a list of the cover art images for a release obtained
95 | from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive),
96 | as well as a summary of what artwork is available.",
97 | "enumValues": null,
98 | "fields": [
99 | {
100 | "args": [
101 | {
102 | "defaultValue": "FULL",
103 | "description": "The size of the image to retrieve. By default, the returned image will
104 | have its full original dimensions, but certain thumbnail sizes may be
105 | retrieved as well.",
106 | "name": "size",
107 | "type": {
108 | "kind": "ENUM",
109 | "name": "CoverArtArchiveImageSize",
110 | "ofType": null,
111 | },
112 | },
113 | ],
114 | "deprecationReason": null,
115 | "description": "The URL of an image depicting the album cover or “main front” of the release,
116 | i.e. the front of the packaging of the audio recording (or in the case of a
117 | digital release, the image associated with it in a digital media store).
118 |
119 | In the MusicBrainz schema, this field is a Boolean value indicating the
120 | presence of a front image, whereas here the value is the URL for the image
121 | itself if one exists. You can check for null if you just want to determine
122 | the presence of an image.",
123 | "isDeprecated": false,
124 | "name": "front",
125 | "type": {
126 | "kind": "SCALAR",
127 | "name": "URLString",
128 | "ofType": null,
129 | },
130 | },
131 | {
132 | "args": [
133 | {
134 | "defaultValue": "FULL",
135 | "description": "The size of the image to retrieve. By default, the returned image will
136 | have its full original dimensions, but certain thumbnail sizes may be
137 | retrieved as well.",
138 | "name": "size",
139 | "type": {
140 | "kind": "ENUM",
141 | "name": "CoverArtArchiveImageSize",
142 | "ofType": null,
143 | },
144 | },
145 | ],
146 | "deprecationReason": null,
147 | "description": "The URL of an image depicting the “main back” of the release, i.e. the back
148 | of the packaging of the audio recording.
149 |
150 | In the MusicBrainz schema, this field is a Boolean value indicating the
151 | presence of a back image, whereas here the value is the URL for the image
152 | itself. You can check for null if you just want to determine the presence of
153 | an image.",
154 | "isDeprecated": false,
155 | "name": "back",
156 | "type": {
157 | "kind": "SCALAR",
158 | "name": "URLString",
159 | "ofType": null,
160 | },
161 | },
162 | {
163 | "args": [],
164 | "deprecationReason": null,
165 | "description": "A list of images depicting the different sides and surfaces of a release’s
166 | media and packaging.",
167 | "isDeprecated": false,
168 | "name": "images",
169 | "type": {
170 | "kind": "NON_NULL",
171 | "name": null,
172 | "ofType": {
173 | "kind": "LIST",
174 | "name": null,
175 | "ofType": {
176 | "kind": "OBJECT",
177 | "name": "CoverArtArchiveImage",
178 | "ofType": null,
179 | },
180 | },
181 | },
182 | },
183 | {
184 | "args": [],
185 | "deprecationReason": null,
186 | "description": "Whether there is artwork present for this release.",
187 | "isDeprecated": false,
188 | "name": "artwork",
189 | "type": {
190 | "kind": "NON_NULL",
191 | "name": null,
192 | "ofType": {
193 | "kind": "SCALAR",
194 | "name": "Boolean",
195 | "ofType": null,
196 | },
197 | },
198 | },
199 | {
200 | "args": [],
201 | "deprecationReason": null,
202 | "description": "The number of artwork images present for this release.",
203 | "isDeprecated": false,
204 | "name": "count",
205 | "type": {
206 | "kind": "NON_NULL",
207 | "name": null,
208 | "ofType": {
209 | "kind": "SCALAR",
210 | "name": "Int",
211 | "ofType": null,
212 | },
213 | },
214 | },
215 | {
216 | "args": [],
217 | "deprecationReason": null,
218 | "description": "The particular release shown in the returned cover art.",
219 | "isDeprecated": false,
220 | "name": "release",
221 | "type": {
222 | "kind": "OBJECT",
223 | "name": "Release",
224 | "ofType": null,
225 | },
226 | },
227 | ],
228 | "inputFields": null,
229 | "interfaces": [],
230 | "kind": "OBJECT",
231 | "name": "CoverArtArchiveRelease",
232 | "possibleTypes": null,
233 | },
234 | {
235 | "description": "The image sizes that may be requested at the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).",
236 | "enumValues": [
237 | {
238 | "deprecationReason": null,
239 | "description": "A maximum dimension of 250px.",
240 | "isDeprecated": false,
241 | "name": "SMALL",
242 | },
243 | {
244 | "deprecationReason": null,
245 | "description": "A maximum dimension of 500px.",
246 | "isDeprecated": false,
247 | "name": "LARGE",
248 | },
249 | {
250 | "deprecationReason": null,
251 | "description": "The image’s original dimensions, with no maximum.",
252 | "isDeprecated": false,
253 | "name": "FULL",
254 | },
255 | ],
256 | "fields": null,
257 | "inputFields": null,
258 | "interfaces": null,
259 | "kind": "ENUM",
260 | "name": "CoverArtArchiveImageSize",
261 | "possibleTypes": null,
262 | },
263 | {
264 | "description": "An individual piece of album artwork from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).",
265 | "enumValues": null,
266 | "fields": [
267 | {
268 | "args": [],
269 | "deprecationReason": null,
270 | "description": "The Internet Archive’s internal file ID for the image.",
271 | "isDeprecated": false,
272 | "name": "fileID",
273 | "type": {
274 | "kind": "NON_NULL",
275 | "name": null,
276 | "ofType": {
277 | "kind": "SCALAR",
278 | "name": "String",
279 | "ofType": null,
280 | },
281 | },
282 | },
283 | {
284 | "args": [],
285 | "deprecationReason": null,
286 | "description": "The URL at which the image can be found.",
287 | "isDeprecated": false,
288 | "name": "image",
289 | "type": {
290 | "kind": "NON_NULL",
291 | "name": null,
292 | "ofType": {
293 | "kind": "SCALAR",
294 | "name": "URLString",
295 | "ofType": null,
296 | },
297 | },
298 | },
299 | {
300 | "args": [],
301 | "deprecationReason": null,
302 | "description": "A set of thumbnails for the image.",
303 | "isDeprecated": false,
304 | "name": "thumbnails",
305 | "type": {
306 | "kind": "NON_NULL",
307 | "name": null,
308 | "ofType": {
309 | "kind": "OBJECT",
310 | "name": "CoverArtArchiveImageThumbnails",
311 | "ofType": null,
312 | },
313 | },
314 | },
315 | {
316 | "args": [],
317 | "deprecationReason": null,
318 | "description": "Whether this image depicts the “main front” of the release.",
319 | "isDeprecated": false,
320 | "name": "front",
321 | "type": {
322 | "kind": "NON_NULL",
323 | "name": null,
324 | "ofType": {
325 | "kind": "SCALAR",
326 | "name": "Boolean",
327 | "ofType": null,
328 | },
329 | },
330 | },
331 | {
332 | "args": [],
333 | "deprecationReason": null,
334 | "description": "Whether this image depicts the “main back” of the release.",
335 | "isDeprecated": false,
336 | "name": "back",
337 | "type": {
338 | "kind": "NON_NULL",
339 | "name": null,
340 | "ofType": {
341 | "kind": "SCALAR",
342 | "name": "Boolean",
343 | "ofType": null,
344 | },
345 | },
346 | },
347 | {
348 | "args": [],
349 | "deprecationReason": null,
350 | "description": "A list of [image types](https://musicbrainz.org/doc/Cover_Art/Types)
351 | describing what part(s) of the release the image includes.",
352 | "isDeprecated": false,
353 | "name": "types",
354 | "type": {
355 | "kind": "NON_NULL",
356 | "name": null,
357 | "ofType": {
358 | "kind": "LIST",
359 | "name": null,
360 | "ofType": {
361 | "kind": "SCALAR",
362 | "name": "String",
363 | "ofType": null,
364 | },
365 | },
366 | },
367 | },
368 | {
369 | "args": [],
370 | "deprecationReason": null,
371 | "description": "The MusicBrainz edit ID.",
372 | "isDeprecated": false,
373 | "name": "edit",
374 | "type": {
375 | "kind": "SCALAR",
376 | "name": "Int",
377 | "ofType": null,
378 | },
379 | },
380 | {
381 | "args": [],
382 | "deprecationReason": null,
383 | "description": "Whether the image was approved by the MusicBrainz edit system.",
384 | "isDeprecated": false,
385 | "name": "approved",
386 | "type": {
387 | "kind": "SCALAR",
388 | "name": "Boolean",
389 | "ofType": null,
390 | },
391 | },
392 | {
393 | "args": [],
394 | "deprecationReason": null,
395 | "description": "A free-text comment left for the image.",
396 | "isDeprecated": false,
397 | "name": "comment",
398 | "type": {
399 | "kind": "SCALAR",
400 | "name": "String",
401 | "ofType": null,
402 | },
403 | },
404 | ],
405 | "inputFields": null,
406 | "interfaces": [],
407 | "kind": "OBJECT",
408 | "name": "CoverArtArchiveImage",
409 | "possibleTypes": null,
410 | },
411 | {
412 | "description": "URLs for thumbnails of different sizes for a particular piece of cover art.",
413 | "enumValues": null,
414 | "fields": [
415 | {
416 | "args": [],
417 | "deprecationReason": null,
418 | "description": "The URL of a small version of the cover art, where the maximum dimension is
419 | 250px.",
420 | "isDeprecated": false,
421 | "name": "small",
422 | "type": {
423 | "kind": "SCALAR",
424 | "name": "URLString",
425 | "ofType": null,
426 | },
427 | },
428 | {
429 | "args": [],
430 | "deprecationReason": null,
431 | "description": "The URL of a large version of the cover art, where the maximum dimension is
432 | 500px.",
433 | "isDeprecated": false,
434 | "name": "large",
435 | "type": {
436 | "kind": "SCALAR",
437 | "name": "URLString",
438 | "ofType": null,
439 | },
440 | },
441 | ],
442 | "inputFields": null,
443 | "interfaces": [],
444 | "kind": "OBJECT",
445 | "name": "CoverArtArchiveImageThumbnails",
446 | "possibleTypes": null,
447 | },
448 | ],
449 | },
450 | }
451 | `;
452 |
453 | exports[`run() with --help arg prints the help message 1`] = `
454 | {
455 | "stderr": "",
456 | "stdout": "
457 | Usage: graphql-markdown [options]
458 |
459 | Output a Markdown document with rendered descriptions and links between types.
460 | The schema may be specified as:
461 |
462 | - a URL to the GraphQL endpoint (the introspection query will be run)
463 | - a GraphQL document containing the schema (.graphql or .gql)
464 | - a JSON document containing the schema (as returned by the introspection query)
465 | - an importable module with the schema as its default export (either an instance
466 | of GraphQLSchema or a JSON object)
467 |
468 | Options:
469 |
470 | --title Change the top heading title (default: 'Schema Types')
471 | --no-title Do not print a default title
472 | --no-toc Do not print table of contents
473 | --toc-fields Expand the table of contents for the listed types
474 | (comma-separated) to link to fields within those types
475 | (e.g. --toc-fields "Query,Mutation,Subscription") or use
476 | the string "*" to link to fields for all types
477 | --prologue Include custom Markdown after the title
478 | --epilogue Include custom Markdown after everything else
479 | --heading-level Heading level to begin at, useful if you are embedding the
480 | output in a document with other sections (default: 1)
481 | --update-file Markdown document to update (between comment markers) or
482 | create (if the file does not exist)
483 | --require If importing the schema from a module, require the specified
484 | module first (useful for e.g. babel-register)
485 | --header Additional header(s) to use in GraphQL request
486 | e.g. --header "Authorization=Bearer ey..."
487 | --version Print version and exit
488 |
489 | ",
490 | }
491 | `;
492 |
493 | exports[`run() with no args prints the help message 1`] = `
494 | {
495 | "stderr": "",
496 | "stdout": "
497 | Usage: graphql-markdown [options]
498 |
499 | Output a Markdown document with rendered descriptions and links between types.
500 | The schema may be specified as:
501 |
502 | - a URL to the GraphQL endpoint (the introspection query will be run)
503 | - a GraphQL document containing the schema (.graphql or .gql)
504 | - a JSON document containing the schema (as returned by the introspection query)
505 | - an importable module with the schema as its default export (either an instance
506 | of GraphQLSchema or a JSON object)
507 |
508 | Options:
509 |
510 | --title Change the top heading title (default: 'Schema Types')
511 | --no-title Do not print a default title
512 | --no-toc Do not print table of contents
513 | --toc-fields Expand the table of contents for the listed types
514 | (comma-separated) to link to fields within those types
515 | (e.g. --toc-fields "Query,Mutation,Subscription") or use
516 | the string "*" to link to fields for all types
517 | --prologue Include custom Markdown after the title
518 | --epilogue Include custom Markdown after everything else
519 | --heading-level Heading level to begin at, useful if you are embedding the
520 | output in a document with other sections (default: 1)
521 | --update-file Markdown document to update (between comment markers) or
522 | create (if the file does not exist)
523 | --require If importing the schema from a module, require the specified
524 | module first (useful for e.g. babel-register)
525 | --header Additional header(s) to use in GraphQL request
526 | e.g. --header "Authorization=Bearer ey..."
527 | --version Print version and exit
528 |
529 | ",
530 | }
531 | `;
532 |
--------------------------------------------------------------------------------
/test/fixtures/cover-art-archive.js:
--------------------------------------------------------------------------------
1 | const resolveFrom = require('resolve-from')
2 | const {
3 | default: graphBrainzSchema,
4 | createSchema,
5 | } = require('graphbrainz/lib/schema')
6 | const { schemaToJSON, diffSchema } = require('../../src/index')
7 |
8 | /**
9 | * Generate a "diff" schema in order to test `diffSchema`.
10 | */
11 | async function generateDiff() {
12 | // Get the instance of `graphql` that `graphbrainz` sees.
13 | const graphql = require(resolveFrom(
14 | require.resolve('graphbrainz'),
15 | 'graphql'
16 | ))
17 |
18 | const extendedSchema = createSchema(graphBrainzSchema, {
19 | extensions: ['graphbrainz/extensions/cover-art-archive'],
20 | })
21 |
22 | const schemaJSON = await schemaToJSON(graphBrainzSchema, { graphql })
23 | const extendedSchemaJSON = await schemaToJSON(extendedSchema, { graphql })
24 |
25 | return diffSchema(schemaJSON, extendedSchemaJSON)
26 | }
27 |
28 | module.exports = generateDiff()
29 |
--------------------------------------------------------------------------------
/test/fixtures/cover-art-archive.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | Table of Contents
5 |
6 | * [Objects](#objects)
7 | * [CoverArtArchiveImage](#coverartarchiveimage)
8 | * [CoverArtArchiveImageThumbnails](#coverartarchiveimagethumbnails)
9 | * [CoverArtArchiveRelease](#coverartarchiverelease)
10 | * [Release](#release)
11 | * [ReleaseGroup](#releasegroup)
12 | * [Enums](#enums)
13 | * [CoverArtArchiveImageSize](#coverartarchiveimagesize)
14 |
15 |
16 |
17 | ## Objects
18 |
19 | ### CoverArtArchiveImage
20 |
21 | An individual piece of album artwork from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).
22 |
23 |
24 |
25 |
26 | Field |
27 | Argument |
28 | Type |
29 | Description |
30 |
31 |
32 |
33 |
34 | fileID |
35 | String! |
36 |
37 |
38 | The Internet Archive’s internal file ID for the image.
39 |
40 | |
41 |
42 |
43 | image |
44 | URLString! |
45 |
46 |
47 | The URL at which the image can be found.
48 |
49 | |
50 |
51 |
52 | thumbnails |
53 | CoverArtArchiveImageThumbnails! |
54 |
55 |
56 | A set of thumbnails for the image.
57 |
58 | |
59 |
60 |
61 | front |
62 | Boolean! |
63 |
64 |
65 | Whether this image depicts the “main front” of the release.
66 |
67 | |
68 |
69 |
70 | back |
71 | Boolean! |
72 |
73 |
74 | Whether this image depicts the “main back” of the release.
75 |
76 | |
77 |
78 |
79 | types |
80 | [String]! |
81 |
82 |
83 | A list of [image types](https://musicbrainz.org/doc/Cover_Art/Types)
84 | describing what part(s) of the release the image includes.
85 |
86 | |
87 |
88 |
89 | edit |
90 | Int |
91 |
92 |
93 | The MusicBrainz edit ID.
94 |
95 | |
96 |
97 |
98 | approved |
99 | Boolean |
100 |
101 |
102 | Whether the image was approved by the MusicBrainz edit system.
103 |
104 | |
105 |
106 |
107 | |
108 | String |
109 |
110 |
111 | A free-text comment left for the image.
112 |
113 | |
114 |
115 |
116 |
117 |
118 | ### CoverArtArchiveImageThumbnails
119 |
120 | URLs for thumbnails of different sizes for a particular piece of cover art.
121 |
122 |
123 |
124 |
125 | Field |
126 | Argument |
127 | Type |
128 | Description |
129 |
130 |
131 |
132 |
133 | small |
134 | URLString |
135 |
136 |
137 | The URL of a small version of the cover art, where the maximum dimension is
138 | 250px.
139 |
140 | |
141 |
142 |
143 | large |
144 | URLString |
145 |
146 |
147 | The URL of a large version of the cover art, where the maximum dimension is
148 | 500px.
149 |
150 | |
151 |
152 |
153 |
154 |
155 | ### CoverArtArchiveRelease
156 |
157 | An object containing a list of the cover art images for a release obtained
158 | from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive),
159 | as well as a summary of what artwork is available.
160 |
161 |
162 |
163 |
164 | Field |
165 | Argument |
166 | Type |
167 | Description |
168 |
169 |
170 |
171 |
172 | front |
173 | URLString |
174 |
175 |
176 | The URL of an image depicting the album cover or “main front” of the release,
177 | i.e. the front of the packaging of the audio recording (or in the case of a
178 | digital release, the image associated with it in a digital media store).
179 |
180 | In the MusicBrainz schema, this field is a Boolean value indicating the
181 | presence of a front image, whereas here the value is the URL for the image
182 | itself if one exists. You can check for null if you just want to determine
183 | the presence of an image.
184 |
185 | |
186 |
187 |
188 | size |
189 | CoverArtArchiveImageSize |
190 |
191 |
192 | The size of the image to retrieve. By default, the returned image will
193 | have its full original dimensions, but certain thumbnail sizes may be
194 | retrieved as well.
195 |
196 | |
197 |
198 |
199 | back |
200 | URLString |
201 |
202 |
203 | The URL of an image depicting the “main back” of the release, i.e. the back
204 | of the packaging of the audio recording.
205 |
206 | In the MusicBrainz schema, this field is a Boolean value indicating the
207 | presence of a back image, whereas here the value is the URL for the image
208 | itself. You can check for null if you just want to determine the presence of
209 | an image.
210 |
211 | |
212 |
213 |
214 | size |
215 | CoverArtArchiveImageSize |
216 |
217 |
218 | The size of the image to retrieve. By default, the returned image will
219 | have its full original dimensions, but certain thumbnail sizes may be
220 | retrieved as well.
221 |
222 | |
223 |
224 |
225 | images |
226 | [CoverArtArchiveImage]! |
227 |
228 |
229 | A list of images depicting the different sides and surfaces of a release’s
230 | media and packaging.
231 |
232 | |
233 |
234 |
235 | artwork |
236 | Boolean! |
237 |
238 |
239 | Whether there is artwork present for this release.
240 |
241 | |
242 |
243 |
244 | count |
245 | Int! |
246 |
247 |
248 | The number of artwork images present for this release.
249 |
250 | |
251 |
252 |
253 | release |
254 | Release |
255 |
256 |
257 | The particular release shown in the returned cover art.
258 |
259 | |
260 |
261 |
262 |
263 |
264 | ### Release
265 |
266 | A [release](https://musicbrainz.org/doc/Release) represents the
267 | unique release (i.e. issuing) of a product on a specific date with specific
268 | release information such as the country, label, barcode, packaging, etc. If you
269 | walk into a store and purchase an album or single, they’re each represented in
270 | MusicBrainz as one release.
271 |
272 |
273 |
274 |
275 | Field |
276 | Argument |
277 | Type |
278 | Description |
279 |
280 |
281 |
282 |
283 | coverArtArchive |
284 | CoverArtArchiveRelease |
285 |
286 |
287 | An object containing a list and summary of the cover art images that are
288 | present for this release from the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).
289 | This field is provided by the Cover Art Archive extension.
290 |
291 | |
292 |
293 |
294 |
295 |
296 | ### ReleaseGroup
297 |
298 | A [release group](https://musicbrainz.org/doc/Release_Group) is
299 | used to group several different releases into a single logical entity. Every
300 | release belongs to one, and only one release group.
301 |
302 | Both release groups and releases are “albums” in a general sense, but with an
303 | important difference: a release is something you can buy as media such as a CD
304 | or a vinyl record, while a release group embraces the overall concept of an
305 | album – it doesn’t matter how many CDs or editions/versions it had.
306 |
307 |
308 |
309 |
310 | Field |
311 | Argument |
312 | Type |
313 | Description |
314 |
315 |
316 |
317 |
318 | coverArtArchive |
319 | CoverArtArchiveRelease |
320 |
321 |
322 | The cover art for a release in the release group, obtained from the
323 | [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive). A
324 | release in the release group will be chosen as representative of the release
325 | group.
326 | This field is provided by the Cover Art Archive extension.
327 |
328 | |
329 |
330 |
331 |
332 |
333 | ## Enums
334 |
335 | ### CoverArtArchiveImageSize
336 |
337 | The image sizes that may be requested at the [Cover Art Archive](https://musicbrainz.org/doc/Cover_Art_Archive).
338 |
339 |
340 |
341 |
342 | Value |
343 | Description |
344 |
345 |
346 |
347 |
348 | SMALL |
349 |
350 |
351 | A maximum dimension of 250px.
352 |
353 | |
354 |
355 |
356 | LARGE |
357 |
358 |
359 | A maximum dimension of 500px.
360 |
361 | |
362 |
363 |
364 | FULL |
365 |
366 |
367 | The image’s original dimensions, with no maximum.
368 |
369 | |
370 |
371 |
372 |
373 |
--------------------------------------------------------------------------------
/test/fixtures/graphbrainz-updateSchema.js:
--------------------------------------------------------------------------------
1 | const resolveFrom = require('resolve-from')
2 | const {
3 | default: graphBrainzSchema,
4 | createSchema,
5 | } = require('graphbrainz/lib/schema')
6 | const { schemaToJSON } = require('../../src/index')
7 |
8 | /**
9 | * Generate an update to the base GraphBrainz schema.
10 | */
11 | function generateSchema() {
12 | // Get the instance of `graphql` that `graphbrainz` sees.
13 | const graphql = require(resolveFrom(
14 | require.resolve('graphbrainz'),
15 | 'graphql'
16 | ))
17 |
18 | const extendedSchema = createSchema(graphBrainzSchema, {
19 | extensions: ['graphbrainz/extensions/cover-art-archive'],
20 | })
21 |
22 | return schemaToJSON(extendedSchema, { graphql })
23 | }
24 |
25 | module.exports = generateSchema()
26 |
--------------------------------------------------------------------------------
/test/fixtures/graphbrainz.graphql:
--------------------------------------------------------------------------------
1 | """
2 | [Aliases](https://musicbrainz.org/doc/Aliases) are variant names
3 | that are mostly used as search help: if a search matches an entity’s alias, the
4 | entity will be given as a result – even if the actual name wouldn’t be.
5 | """
6 | type Alias {
7 | """
8 | The aliased name of the entity.
9 | """
10 | name: String
11 |
12 | """
13 | The string to use for the purpose of ordering by name (for
14 | example, by moving articles like ‘the’ to the end or a person’s last name to
15 | the front).
16 | """
17 | sortName: String
18 |
19 | """
20 | The locale (language and/or country) in which the alias is
21 | used.
22 | """
23 | locale: Locale
24 |
25 | """
26 | Whether this is the main alias for the entity in the
27 | specified locale (this could mean the most recent or the most common).
28 | """
29 | primary: Boolean
30 |
31 | """
32 | The type or purpose of the alias – whether it is a variant,
33 | search hint, etc.
34 | """
35 | type: String
36 |
37 | """
38 | The MBID associated with the value of the `type`
39 | field.
40 | """
41 | typeID: MBID
42 | }
43 |
44 | """
45 | [Areas](https://musicbrainz.org/doc/Area) are geographic regions
46 | or settlements (countries, cities, or the like).
47 | """
48 | type Area implements Node & Entity {
49 | """
50 | The ID of an object
51 | """
52 | id: ID!
53 |
54 | """
55 | The MBID of the entity.
56 | """
57 | mbid: MBID!
58 |
59 | """
60 | The official name of the entity.
61 | """
62 | name: String
63 |
64 | """
65 | The string to use for the purpose of ordering by name (for
66 | example, by moving articles like ‘the’ to the end or a person’s last name to
67 | the front).
68 | """
69 | sortName: String
70 |
71 | """
72 | A comment used to help distinguish identically named entitites.
73 | """
74 | disambiguation: String
75 |
76 | """
77 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
78 | alternate names or misspellings.
79 | """
80 | aliases: [Alias]
81 |
82 | """
83 | [ISO 3166 codes](https://en.wikipedia.org/wiki/ISO_3166) are
84 | the codes assigned by ISO to countries and subdivisions.
85 | """
86 | isoCodes(
87 | """
88 | Specify the particular ISO standard codes to retrieve.
89 | Available ISO standards are 3166-1, 3166-2, and 3166-3.
90 | """
91 | standard: String = "3166-1"
92 | ): [String]
93 |
94 | """
95 | The type of area (country, city, etc. – see the [possible
96 | values](https://musicbrainz.org/doc/Area)).
97 | """
98 | type: String
99 |
100 | """
101 | The MBID associated with the value of the `type`
102 | field.
103 | """
104 | typeID: MBID
105 |
106 | """
107 | A list of artists linked to this entity.
108 | """
109 | artists(after: String, first: Int): ArtistConnection
110 |
111 | """
112 | A list of events linked to this entity.
113 | """
114 | events(after: String, first: Int): EventConnection
115 |
116 | """
117 | A list of labels linked to this entity.
118 | """
119 | labels(after: String, first: Int): LabelConnection
120 |
121 | """
122 | A list of places linked to this entity.
123 | """
124 | places(after: String, first: Int): PlaceConnection
125 |
126 | """
127 | A list of releases linked to this entity.
128 | """
129 | releases(
130 | """
131 | Filter by one or more release group types.
132 | """
133 | type: [ReleaseGroupType]
134 |
135 | """
136 | Filter by one or more release statuses.
137 | """
138 | status: [ReleaseStatus]
139 | after: String
140 | first: Int
141 | ): ReleaseConnection
142 |
143 | """
144 | Relationships between this entity and other entitites.
145 | """
146 | relationships: Relationships
147 |
148 | """
149 | A list of collections containing this entity.
150 | """
151 | collections(after: String, first: Int): CollectionConnection
152 |
153 | """
154 | A list of tags linked to this entity.
155 | """
156 | tags(after: String, first: Int): TagConnection
157 | }
158 |
159 | """
160 | A connection to a list of items.
161 | """
162 | type AreaConnection {
163 | """
164 | Information to aid in pagination.
165 | """
166 | pageInfo: PageInfo!
167 |
168 | """
169 | A list of edges.
170 | """
171 | edges: [AreaEdge]
172 |
173 | """
174 | A list of nodes in the connection (without going through the
175 | `edges` field).
176 | """
177 | nodes: [Area]
178 |
179 | """
180 | A count of the total number of items in this connection,
181 | ignoring pagination.
182 | """
183 | totalCount: Int
184 | }
185 |
186 | """
187 | An edge in a connection.
188 | """
189 | type AreaEdge {
190 | """
191 | The item at the end of the edge
192 | """
193 | node: Area
194 |
195 | """
196 | A cursor for use in pagination
197 | """
198 | cursor: String!
199 |
200 | """
201 | The relevancy score (0–100) assigned by the search engine, if
202 | these results were found through a search.
203 | """
204 | score: Int
205 | }
206 |
207 | """
208 | An [artist](https://musicbrainz.org/doc/Artist) is generally a
209 | musician, group of musicians, or other music professional (like a producer or
210 | engineer). Occasionally, it can also be a non-musical person (like a
211 | photographer, an illustrator, or a poet whose writings are set to music), or
212 | even a fictional character.
213 | """
214 | type Artist implements Node & Entity {
215 | """
216 | The ID of an object
217 | """
218 | id: ID!
219 |
220 | """
221 | The MBID of the entity.
222 | """
223 | mbid: MBID!
224 |
225 | """
226 | The official name of the entity.
227 | """
228 | name: String
229 |
230 | """
231 | The string to use for the purpose of ordering by name (for
232 | example, by moving articles like ‘the’ to the end or a person’s last name to
233 | the front).
234 | """
235 | sortName: String
236 |
237 | """
238 | A comment used to help distinguish identically named entitites.
239 | """
240 | disambiguation: String
241 |
242 | """
243 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
244 | alternate names or misspellings.
245 | """
246 | aliases: [Alias]
247 |
248 | """
249 | The country with which an artist is primarily identified. It
250 | is often, but not always, its birth/formation country.
251 | """
252 | country: String
253 |
254 | """
255 | The area with which an artist is primarily identified. It
256 | is often, but not always, its birth/formation country.
257 | """
258 | area: Area
259 |
260 | """
261 | The area in which an artist began their career (or where
262 | they were born, if the artist is a person).
263 | """
264 | beginArea: Area
265 |
266 | """
267 | The area in which an artist ended their career (or where
268 | they died, if the artist is a person).
269 | """
270 | endArea: Area
271 |
272 | """
273 | The begin and end dates of the entity’s existence. Its exact
274 | meaning depends on the type of entity.
275 | """
276 | lifeSpan: LifeSpan
277 |
278 | """
279 | Whether a person or character identifies as male, female, or
280 | neither. Groups do not have genders.
281 | """
282 | gender: String
283 |
284 | """
285 | The MBID associated with the value of the `gender`
286 | field.
287 | """
288 | genderID: MBID
289 |
290 | """
291 | Whether an artist is a person, a group, or something else.
292 | """
293 | type: String
294 |
295 | """
296 | The MBID associated with the value of the `type`
297 | field.
298 | """
299 | typeID: MBID
300 |
301 | """
302 | List of [Interested Parties Information](https://musicbrainz.org/doc/IPI)
303 | (IPI) codes for the artist.
304 | """
305 | ipis: [IPI]
306 |
307 | """
308 | List of [International Standard Name Identifier](https://musicbrainz.org/doc/ISNI)
309 | (ISNI) codes for the artist.
310 | """
311 | isnis: [ISNI]
312 |
313 | """
314 | A list of recordings linked to this entity.
315 | """
316 | recordings(after: String, first: Int): RecordingConnection
317 |
318 | """
319 | A list of releases linked to this entity.
320 | """
321 | releases(
322 | """
323 | Filter by one or more release group types.
324 | """
325 | type: [ReleaseGroupType]
326 |
327 | """
328 | Filter by one or more release statuses.
329 | """
330 | status: [ReleaseStatus]
331 | after: String
332 | first: Int
333 | ): ReleaseConnection
334 |
335 | """
336 | A list of release groups linked to this entity.
337 | """
338 | releaseGroups(
339 | """
340 | Filter by one or more release group types.
341 | """
342 | type: [ReleaseGroupType]
343 | after: String
344 | first: Int
345 | ): ReleaseGroupConnection
346 |
347 | """
348 | A list of works linked to this entity.
349 | """
350 | works(after: String, first: Int): WorkConnection
351 |
352 | """
353 | Relationships between this entity and other entitites.
354 | """
355 | relationships: Relationships
356 |
357 | """
358 | A list of collections containing this entity.
359 | """
360 | collections(after: String, first: Int): CollectionConnection
361 |
362 | """
363 | The rating users have given to this entity.
364 | """
365 | rating: Rating
366 |
367 | """
368 | A list of tags linked to this entity.
369 | """
370 | tags(after: String, first: Int): TagConnection
371 | }
372 |
373 | """
374 | A connection to a list of items.
375 | """
376 | type ArtistConnection {
377 | """
378 | Information to aid in pagination.
379 | """
380 | pageInfo: PageInfo!
381 |
382 | """
383 | A list of edges.
384 | """
385 | edges: [ArtistEdge]
386 |
387 | """
388 | A list of nodes in the connection (without going through the
389 | `edges` field).
390 | """
391 | nodes: [Artist]
392 |
393 | """
394 | A count of the total number of items in this connection,
395 | ignoring pagination.
396 | """
397 | totalCount: Int
398 | }
399 |
400 | """
401 | [Artist credits](https://musicbrainz.org/doc/Artist_Credits)
402 | indicate who is the main credited artist (or artists) for releases, release
403 | groups, tracks, and recordings, and how they are credited. They consist of
404 | artists, with (optionally) their names as credited in the specific release,
405 | track, etc., and join phrases between them.
406 | """
407 | type ArtistCredit {
408 | """
409 | The entity representing the artist referenced in the
410 | credits.
411 | """
412 | artist: Artist
413 |
414 | """
415 | The name of the artist as credited in the specific release,
416 | track, etc.
417 | """
418 | name: String
419 |
420 | """
421 | Join phrases might include words and/or punctuation to
422 | separate artist names as they appear on the release, track, etc.
423 | """
424 | joinPhrase: String
425 | }
426 |
427 | """
428 | An edge in a connection.
429 | """
430 | type ArtistEdge {
431 | """
432 | The item at the end of the edge
433 | """
434 | node: Artist
435 |
436 | """
437 | A cursor for use in pagination
438 | """
439 | cursor: String!
440 |
441 | """
442 | The relevancy score (0–100) assigned by the search engine, if
443 | these results were found through a search.
444 | """
445 | score: Int
446 | }
447 |
448 | """
449 | An [Amazon Standard Identification Number](https://musicbrainz.org/doc/ASIN)
450 | (ASIN) is a 10-character alphanumeric unique identifier assigned by Amazon.com
451 | and its partners for product identification within the Amazon organization.
452 | """
453 | scalar ASIN
454 |
455 | """
456 | A query for all MusicBrainz entities directly linked to another
457 | entity.
458 | """
459 | type BrowseQuery {
460 | """
461 | Browse area entities linked to the given arguments.
462 | """
463 | areas(
464 | """
465 | The MBID of a collection in which the entity is found.
466 | """
467 | collection: MBID
468 | after: String
469 | first: Int
470 | ): AreaConnection
471 |
472 | """
473 | Browse artist entities linked to the given arguments.
474 | """
475 | artists(
476 | """
477 | The MBID of an area to which the entity is linked.
478 | """
479 | area: MBID
480 |
481 | """
482 | The MBID of a collection in which the entity is found.
483 | """
484 | collection: MBID
485 |
486 | """
487 | The MBID of a recording to which the entity is linked.
488 | """
489 | recording: MBID
490 |
491 | """
492 | The MBID of a release to which the entity is linked.
493 | """
494 | release: MBID
495 |
496 | """
497 | The MBID of a release group to which the entity is linked.
498 | """
499 | releaseGroup: MBID
500 |
501 | """
502 | The MBID of a work to which the entity is linked.
503 | """
504 | work: MBID
505 | after: String
506 | first: Int
507 | ): ArtistConnection
508 |
509 | """
510 | Browse collection entities linked to the given arguments.
511 | """
512 | collections(
513 | """
514 | The MBID of an area to which the entity is linked.
515 | """
516 | area: MBID
517 |
518 | """
519 | The MBID of an artist to which the entity is linked.
520 | """
521 | artist: MBID
522 |
523 | """
524 | The username of the editor who created the collection.
525 | """
526 | editor: String
527 |
528 | """
529 | The MBID of an event to which the entity is linked.
530 | """
531 | event: MBID
532 |
533 | """
534 | The MBID of a label to which the entity is linked.
535 | """
536 | label: MBID
537 |
538 | """
539 | The MBID of a place to which the entity is linked.
540 | """
541 | place: MBID
542 |
543 | """
544 | The MBID of a recording to which the entity is linked.
545 | """
546 | recording: MBID
547 |
548 | """
549 | The MBID of a release to which the entity is linked.
550 | """
551 | release: MBID
552 |
553 | """
554 | The MBID of a release group to which the entity is linked.
555 | """
556 | releaseGroup: MBID
557 |
558 | """
559 | The MBID of a work to which the entity is linked.
560 | """
561 | work: MBID
562 | after: String
563 | first: Int
564 | ): CollectionConnection
565 |
566 | """
567 | Browse event entities linked to the given arguments.
568 | """
569 | events(
570 | """
571 | The MBID of an area to which the entity is linked.
572 | """
573 | area: MBID
574 |
575 | """
576 | The MBID of an artist to which the entity is linked.
577 | """
578 | artist: MBID
579 |
580 | """
581 | The MBID of a collection in which the entity is found.
582 | """
583 | collection: MBID
584 |
585 | """
586 | The MBID of a place to which the entity is linked.
587 | """
588 | place: MBID
589 | after: String
590 | first: Int
591 | ): EventConnection
592 |
593 | """
594 | Browse label entities linked to the given arguments.
595 | """
596 | labels(
597 | """
598 | The MBID of an area to which the entity is linked.
599 | """
600 | area: MBID
601 |
602 | """
603 | The MBID of a collection in which the entity is found.
604 | """
605 | collection: MBID
606 |
607 | """
608 | The MBID of a release to which the entity is linked.
609 | """
610 | release: MBID
611 | after: String
612 | first: Int
613 | ): LabelConnection
614 |
615 | """
616 | Browse place entities linked to the given arguments.
617 | """
618 | places(
619 | """
620 | The MBID of an area to which the entity is linked.
621 | """
622 | area: MBID
623 |
624 | """
625 | The MBID of a collection in which the entity is found.
626 | """
627 | collection: MBID
628 | after: String
629 | first: Int
630 | ): PlaceConnection
631 |
632 | """
633 | Browse recording entities linked to the given arguments.
634 | """
635 | recordings(
636 | """
637 | The MBID of an artist to which the entity is linked.
638 | """
639 | artist: MBID
640 |
641 | """
642 | The MBID of a collection in which the entity is found.
643 | """
644 | collection: MBID
645 |
646 | """
647 | The [International Standard Recording Code](https://musicbrainz.org/doc/ISRC)
648 | (ISRC) of the recording.
649 | """
650 | isrc: ISRC
651 |
652 | """
653 | The MBID of a release to which the entity is linked.
654 | """
655 | release: MBID
656 | after: String
657 | first: Int
658 | ): RecordingConnection
659 |
660 | """
661 | Browse release entities linked to the given arguments.
662 | """
663 | releases(
664 | """
665 | The MBID of an area to which the entity is linked.
666 | """
667 | area: MBID
668 |
669 | """
670 | The MBID of an artist to which the entity is linked.
671 | """
672 | artist: MBID
673 |
674 | """
675 | The MBID of a collection in which the entity is found.
676 | """
677 | collection: MBID
678 |
679 | """
680 | A [disc ID](https://musicbrainz.org/doc/Disc_ID)
681 | associated with the release.
682 | """
683 | discID: DiscID
684 |
685 | """
686 | The MBID of a label to which the entity is linked.
687 | """
688 | label: MBID
689 |
690 | """
691 | The MBID of a recording to which the entity is linked.
692 | """
693 | recording: MBID
694 |
695 | """
696 | The MBID of a release group to which the entity is linked.
697 | """
698 | releaseGroup: MBID
699 |
700 | """
701 | The MBID of a track that is included in the release.
702 | """
703 | track: MBID
704 |
705 | """
706 | The MBID of an artist that appears on a track in the
707 | release, but is not included in the credits for the release itself.
708 | """
709 | trackArtist: MBID
710 |
711 | """
712 | Filter by one or more release group types.
713 | """
714 | type: [ReleaseGroupType]
715 |
716 | """
717 | Filter by one or more release statuses.
718 | """
719 | status: [ReleaseStatus]
720 | after: String
721 | first: Int
722 | ): ReleaseConnection
723 |
724 | """
725 | Browse release group entities linked to the given arguments.
726 | """
727 | releaseGroups(
728 | """
729 | The MBID of an artist to which the entity is linked.
730 | """
731 | artist: MBID
732 |
733 | """
734 | The MBID of a collection in which the entity is found.
735 | """
736 | collection: MBID
737 |
738 | """
739 | The MBID of a release to which the entity is linked.
740 | """
741 | release: MBID
742 |
743 | """
744 | Filter by one or more release group types.
745 | """
746 | type: [ReleaseGroupType]
747 | after: String
748 | first: Int
749 | ): ReleaseGroupConnection
750 |
751 | """
752 | Browse work entities linked to the given arguments.
753 | """
754 | works(
755 | """
756 | The MBID of an artist to which the entity is linked.
757 | """
758 | artist: MBID
759 |
760 | """
761 | The MBID of a collection in which the entity is found.
762 | """
763 | collection: MBID
764 |
765 | """
766 | The [International Standard Musical Work Code](https://musicbrainz.org/doc/ISWC)
767 | (ISWC) of the work.
768 | """
769 | iswc: ISWC
770 | after: String
771 | first: Int
772 | ): WorkConnection
773 | }
774 |
775 | """
776 | [Collections](https://musicbrainz.org/doc/Collections) are
777 | lists of entities that users can create.
778 | """
779 | type Collection implements Node & Entity {
780 | """
781 | The ID of an object
782 | """
783 | id: ID!
784 |
785 | """
786 | The MBID of the entity.
787 | """
788 | mbid: MBID!
789 |
790 | """
791 | The official name of the entity.
792 | """
793 | name: String
794 |
795 | """
796 | The username of the editor who created the collection.
797 | """
798 | editor: String!
799 |
800 | """
801 | The type of entity listed in the collection.
802 | """
803 | entityType: String!
804 |
805 | """
806 | The type of collection.
807 | """
808 | type: String
809 |
810 | """
811 | The MBID associated with the value of the `type`
812 | field.
813 | """
814 | typeID: MBID
815 |
816 | """
817 | The list of areas found in this collection.
818 | """
819 | areas(after: String, first: Int): AreaConnection
820 |
821 | """
822 | The list of artists found in this collection.
823 | """
824 | artists(after: String, first: Int): ArtistConnection
825 |
826 | """
827 | The list of events found in this collection.
828 | """
829 | events(after: String, first: Int): EventConnection
830 |
831 | """
832 | The list of instruments found in this collection.
833 | """
834 | instruments(after: String, first: Int): InstrumentConnection
835 |
836 | """
837 | The list of labels found in this collection.
838 | """
839 | labels(after: String, first: Int): LabelConnection
840 |
841 | """
842 | The list of places found in this collection.
843 | """
844 | places(after: String, first: Int): PlaceConnection
845 |
846 | """
847 | The list of recordings found in this collection.
848 | """
849 | recordings(after: String, first: Int): RecordingConnection
850 |
851 | """
852 | The list of releases found in this collection.
853 | """
854 | releases(
855 | """
856 | Filter by one or more release group types.
857 | """
858 | type: [ReleaseGroupType]
859 |
860 | """
861 | Filter by one or more release statuses.
862 | """
863 | status: [ReleaseStatus]
864 | after: String
865 | first: Int
866 | ): ReleaseConnection
867 |
868 | """
869 | The list of release groups found in this collection.
870 | """
871 | releaseGroups(
872 | """
873 | Filter by one or more release group types.
874 | """
875 | type: [ReleaseGroupType]
876 | after: String
877 | first: Int
878 | ): ReleaseGroupConnection
879 |
880 | """
881 | The list of series found in this collection.
882 | """
883 | series(after: String, first: Int): SeriesConnection
884 |
885 | """
886 | The list of works found in this collection.
887 | """
888 | works(after: String, first: Int): WorkConnection
889 | }
890 |
891 | """
892 | A connection to a list of items.
893 | """
894 | type CollectionConnection {
895 | """
896 | Information to aid in pagination.
897 | """
898 | pageInfo: PageInfo!
899 |
900 | """
901 | A list of edges.
902 | """
903 | edges: [CollectionEdge]
904 |
905 | """
906 | A list of nodes in the connection (without going through the
907 | `edges` field).
908 | """
909 | nodes: [Collection]
910 |
911 | """
912 | A count of the total number of items in this connection,
913 | ignoring pagination.
914 | """
915 | totalCount: Int
916 | }
917 |
918 | """
919 | An edge in a connection.
920 | """
921 | type CollectionEdge {
922 | """
923 | The item at the end of the edge
924 | """
925 | node: Collection
926 |
927 | """
928 | A cursor for use in pagination
929 | """
930 | cursor: String!
931 |
932 | """
933 | The relevancy score (0–100) assigned by the search engine, if
934 | these results were found through a search.
935 | """
936 | score: Int
937 | }
938 |
939 | """
940 | Geographic coordinates described with latitude and longitude.
941 | """
942 | type Coordinates {
943 | """
944 | The north–south position of a point on the Earth’s surface.
945 | """
946 | latitude: Degrees
947 |
948 | """
949 | The east–west position of a point on the Earth’s surface.
950 | """
951 | longitude: Degrees
952 | }
953 |
954 | """
955 | Year, month (optional), and day (optional) in YYYY-MM-DD format.
956 | """
957 | scalar Date
958 |
959 | """
960 | Decimal degrees, used for latitude and longitude.
961 | """
962 | scalar Degrees
963 |
964 | """
965 | Information about the physical CD and releases associated with a
966 | particular [disc ID](https://musicbrainz.org/doc/Disc_ID).
967 | """
968 | type Disc implements Node {
969 | """
970 | The ID of an object
971 | """
972 | id: ID!
973 |
974 | """
975 | The [disc ID](https://musicbrainz.org/doc/Disc_ID) of this disc.
976 | """
977 | discID: DiscID!
978 |
979 | """
980 | The number of offsets (tracks) on the disc.
981 | """
982 | offsetCount: Int!
983 |
984 | """
985 | The sector offset of each track on the disc.
986 | """
987 | offsets: [Int]
988 |
989 | """
990 | The sector offset of the lead-out (the end of the disc).
991 | """
992 | sectors: Int!
993 |
994 | """
995 | The list of releases linked to this disc ID.
996 | """
997 | releases(after: String, first: Int): ReleaseConnection
998 | }
999 |
1000 | """
1001 | [Disc ID](https://musicbrainz.org/doc/Disc_ID) is the code
1002 | number which MusicBrainz uses to link a physical CD to a [release](https://musicbrainz.org/doc/Release)
1003 | listing.
1004 |
1005 | A release may have any number of disc IDs, and a disc ID may be linked to
1006 | multiple releases. This is because disc ID calculation involves a hash of the
1007 | frame offsets of the CD tracks.
1008 |
1009 | Different pressing of a CD often have slightly different frame offsets, and
1010 | hence different disc IDs.
1011 |
1012 | Conversely, two different CDs may happen to have exactly the same set of frame
1013 | offsets and hence the same disc ID.
1014 | """
1015 | scalar DiscID
1016 |
1017 | """
1018 | A length of time, in milliseconds.
1019 | """
1020 | scalar Duration
1021 |
1022 | """
1023 | An entity in the MusicBrainz schema.
1024 | """
1025 | interface Entity {
1026 | """
1027 | The MBID of the entity.
1028 | """
1029 | mbid: MBID!
1030 | }
1031 |
1032 | """
1033 | An [event](https://musicbrainz.org/doc/Event) refers to an
1034 | organised event which people can attend, and is relevant to MusicBrainz.
1035 | Generally this means live performances, like concerts and festivals.
1036 | """
1037 | type Event implements Node & Entity {
1038 | """
1039 | The ID of an object
1040 | """
1041 | id: ID!
1042 |
1043 | """
1044 | The MBID of the entity.
1045 | """
1046 | mbid: MBID!
1047 |
1048 | """
1049 | The official name of the entity.
1050 | """
1051 | name: String
1052 |
1053 | """
1054 | A comment used to help distinguish identically named entitites.
1055 | """
1056 | disambiguation: String
1057 |
1058 | """
1059 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
1060 | alternate names or misspellings.
1061 | """
1062 | aliases: [Alias]
1063 |
1064 | """
1065 | The begin and end dates of the entity’s existence. Its exact
1066 | meaning depends on the type of entity.
1067 | """
1068 | lifeSpan: LifeSpan
1069 |
1070 | """
1071 | The start time of the event.
1072 | """
1073 | time: Time
1074 |
1075 | """
1076 | Whether or not the event took place.
1077 | """
1078 | cancelled: Boolean
1079 |
1080 | """
1081 | A list of songs performed, optionally including links to
1082 | artists and works. See the [setlist documentation](https://musicbrainz.org/doc/Event/Setlist)
1083 | for syntax and examples.
1084 | """
1085 | setlist: String
1086 |
1087 | """
1088 | What kind of event the event is, e.g. concert, festival, etc.
1089 | """
1090 | type: String
1091 |
1092 | """
1093 | The MBID associated with the value of the `type`
1094 | field.
1095 | """
1096 | typeID: MBID
1097 |
1098 | """
1099 | Relationships between this entity and other entitites.
1100 | """
1101 | relationships: Relationships
1102 |
1103 | """
1104 | A list of collections containing this entity.
1105 | """
1106 | collections(after: String, first: Int): CollectionConnection
1107 |
1108 | """
1109 | The rating users have given to this entity.
1110 | """
1111 | rating: Rating
1112 |
1113 | """
1114 | A list of tags linked to this entity.
1115 | """
1116 | tags(after: String, first: Int): TagConnection
1117 | }
1118 |
1119 | """
1120 | A connection to a list of items.
1121 | """
1122 | type EventConnection {
1123 | """
1124 | Information to aid in pagination.
1125 | """
1126 | pageInfo: PageInfo!
1127 |
1128 | """
1129 | A list of edges.
1130 | """
1131 | edges: [EventEdge]
1132 |
1133 | """
1134 | A list of nodes in the connection (without going through the
1135 | `edges` field).
1136 | """
1137 | nodes: [Event]
1138 |
1139 | """
1140 | A count of the total number of items in this connection,
1141 | ignoring pagination.
1142 | """
1143 | totalCount: Int
1144 | }
1145 |
1146 | """
1147 | An edge in a connection.
1148 | """
1149 | type EventEdge {
1150 | """
1151 | The item at the end of the edge
1152 | """
1153 | node: Event
1154 |
1155 | """
1156 | A cursor for use in pagination
1157 | """
1158 | cursor: String!
1159 |
1160 | """
1161 | The relevancy score (0–100) assigned by the search engine, if
1162 | these results were found through a search.
1163 | """
1164 | score: Int
1165 | }
1166 |
1167 | """
1168 | [Instruments](https://musicbrainz.org/doc/Instrument) are
1169 | devices created or adapted to make musical sounds. Instruments are primarily
1170 | used in relationships between two other entities.
1171 | """
1172 | type Instrument implements Node & Entity {
1173 | """
1174 | The ID of an object
1175 | """
1176 | id: ID!
1177 |
1178 | """
1179 | The MBID of the entity.
1180 | """
1181 | mbid: MBID!
1182 |
1183 | """
1184 | The official name of the entity.
1185 | """
1186 | name: String
1187 |
1188 | """
1189 | A comment used to help distinguish identically named entitites.
1190 | """
1191 | disambiguation: String
1192 |
1193 | """
1194 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
1195 | alternate names or misspellings.
1196 | """
1197 | aliases: [Alias]
1198 |
1199 | """
1200 | A brief description of the main characteristics of the
1201 | instrument.
1202 | """
1203 | description: String
1204 |
1205 | """
1206 | The type categorises the instrument by the way the sound is
1207 | created, similar to the [Hornbostel-Sachs](https://en.wikipedia.org/wiki/Hornbostel%E2%80%93Sachs)
1208 | classification.
1209 | """
1210 | type: String
1211 |
1212 | """
1213 | The MBID associated with the value of the `type`
1214 | field.
1215 | """
1216 | typeID: MBID
1217 |
1218 | """
1219 | Relationships between this entity and other entitites.
1220 | """
1221 | relationships: Relationships
1222 |
1223 | """
1224 | A list of collections containing this entity.
1225 | """
1226 | collections(after: String, first: Int): CollectionConnection
1227 |
1228 | """
1229 | A list of tags linked to this entity.
1230 | """
1231 | tags(after: String, first: Int): TagConnection
1232 | }
1233 |
1234 | """
1235 | A connection to a list of items.
1236 | """
1237 | type InstrumentConnection {
1238 | """
1239 | Information to aid in pagination.
1240 | """
1241 | pageInfo: PageInfo!
1242 |
1243 | """
1244 | A list of edges.
1245 | """
1246 | edges: [InstrumentEdge]
1247 |
1248 | """
1249 | A list of nodes in the connection (without going through the
1250 | `edges` field).
1251 | """
1252 | nodes: [Instrument]
1253 |
1254 | """
1255 | A count of the total number of items in this connection,
1256 | ignoring pagination.
1257 | """
1258 | totalCount: Int
1259 | }
1260 |
1261 | """
1262 | An edge in a connection.
1263 | """
1264 | type InstrumentEdge {
1265 | """
1266 | The item at the end of the edge
1267 | """
1268 | node: Instrument
1269 |
1270 | """
1271 | A cursor for use in pagination
1272 | """
1273 | cursor: String!
1274 |
1275 | """
1276 | The relevancy score (0–100) assigned by the search engine, if
1277 | these results were found through a search.
1278 | """
1279 | score: Int
1280 | }
1281 |
1282 | """
1283 | An [Interested Parties Information](https://musicbrainz.org/doc/IPI)
1284 | (IPI) code is an identifying number assigned by the CISAC database for musical
1285 | rights management.
1286 | """
1287 | scalar IPI
1288 |
1289 | """
1290 | The [International Standard Name Identifier](https://musicbrainz.org/doc/ISNI)
1291 | (ISNI) is an ISO standard for uniquely identifying the public identities of
1292 | contributors to media content.
1293 | """
1294 | scalar ISNI
1295 |
1296 | """
1297 | The [International Standard Recording Code](https://musicbrainz.org/doc/ISRC)
1298 | (ISRC) is an identification system for audio and music video recordings. It is
1299 | standarized by the [IFPI](http://www.ifpi.org/) in ISO 3901:2001 and used by
1300 | IFPI members to assign a unique identifier to every distinct sound recording
1301 | they release. An ISRC identifies a particular [sound recording](https://musicbrainz.org/doc/Recording),
1302 | not the song itself. Therefore, different recordings, edits, remixes and
1303 | remasters of the same song will each be assigned their own ISRC. However, note
1304 | that same recording should carry the same ISRC in all countries/territories.
1305 | Songs are identified by analogous [International Standard Musical Work Codes](https://musicbrainz.org/doc/ISWC)
1306 | (ISWCs).
1307 | """
1308 | scalar ISRC
1309 |
1310 | """
1311 | The [International Standard Musical Work Code](https://musicbrainz.org/doc/ISWC)
1312 | (ISWC) is an ISO standard similar to ISBNs for identifying musical works /
1313 | compositions.
1314 | """
1315 | scalar ISWC
1316 |
1317 | """
1318 | [Labels](https://musicbrainz.org/doc/Label) represent mostly
1319 | (but not only) imprints. To a lesser extent, a label entity may be created to
1320 | represent a record company.
1321 | """
1322 | type Label implements Node & Entity {
1323 | """
1324 | The ID of an object
1325 | """
1326 | id: ID!
1327 |
1328 | """
1329 | The MBID of the entity.
1330 | """
1331 | mbid: MBID!
1332 |
1333 | """
1334 | The official name of the entity.
1335 | """
1336 | name: String
1337 |
1338 | """
1339 | The string to use for the purpose of ordering by name (for
1340 | example, by moving articles like ‘the’ to the end or a person’s last name to
1341 | the front).
1342 | """
1343 | sortName: String
1344 |
1345 | """
1346 | A comment used to help distinguish identically named entitites.
1347 | """
1348 | disambiguation: String
1349 |
1350 | """
1351 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
1352 | alternate names or misspellings.
1353 | """
1354 | aliases: [Alias]
1355 |
1356 | """
1357 | The country of origin for the label.
1358 | """
1359 | country: String
1360 |
1361 | """
1362 | The area in which the label is based.
1363 | """
1364 | area: Area
1365 |
1366 | """
1367 | The begin and end dates of the entity’s existence. Its exact
1368 | meaning depends on the type of entity.
1369 | """
1370 | lifeSpan: LifeSpan
1371 |
1372 | """
1373 | The [“LC” code](https://musicbrainz.org/doc/Label/Label_Code)
1374 | of the label.
1375 | """
1376 | labelCode: Int
1377 |
1378 | """
1379 | List of [Interested Parties Information](https://musicbrainz.org/doc/IPI)
1380 | codes for the label.
1381 | """
1382 | ipis: [IPI]
1383 |
1384 | """
1385 | A type describing the main activity of the label, e.g.
1386 | imprint, production, distributor, rights society, etc.
1387 | """
1388 | type: String
1389 |
1390 | """
1391 | The MBID associated with the value of the `type`
1392 | field.
1393 | """
1394 | typeID: MBID
1395 |
1396 | """
1397 | A list of releases linked to this entity.
1398 | """
1399 | releases(
1400 | """
1401 | Filter by one or more release group types.
1402 | """
1403 | type: [ReleaseGroupType]
1404 |
1405 | """
1406 | Filter by one or more release statuses.
1407 | """
1408 | status: [ReleaseStatus]
1409 | after: String
1410 | first: Int
1411 | ): ReleaseConnection
1412 |
1413 | """
1414 | Relationships between this entity and other entitites.
1415 | """
1416 | relationships: Relationships
1417 |
1418 | """
1419 | A list of collections containing this entity.
1420 | """
1421 | collections(after: String, first: Int): CollectionConnection
1422 |
1423 | """
1424 | The rating users have given to this entity.
1425 | """
1426 | rating: Rating
1427 |
1428 | """
1429 | A list of tags linked to this entity.
1430 | """
1431 | tags(after: String, first: Int): TagConnection
1432 | }
1433 |
1434 | """
1435 | A connection to a list of items.
1436 | """
1437 | type LabelConnection {
1438 | """
1439 | Information to aid in pagination.
1440 | """
1441 | pageInfo: PageInfo!
1442 |
1443 | """
1444 | A list of edges.
1445 | """
1446 | edges: [LabelEdge]
1447 |
1448 | """
1449 | A list of nodes in the connection (without going through the
1450 | `edges` field).
1451 | """
1452 | nodes: [Label]
1453 |
1454 | """
1455 | A count of the total number of items in this connection,
1456 | ignoring pagination.
1457 | """
1458 | totalCount: Int
1459 | }
1460 |
1461 | """
1462 | An edge in a connection.
1463 | """
1464 | type LabelEdge {
1465 | """
1466 | The item at the end of the edge
1467 | """
1468 | node: Label
1469 |
1470 | """
1471 | A cursor for use in pagination
1472 | """
1473 | cursor: String!
1474 |
1475 | """
1476 | The relevancy score (0–100) assigned by the search engine, if
1477 | these results were found through a search.
1478 | """
1479 | score: Int
1480 | }
1481 |
1482 | """
1483 | Fields indicating the begin and end date of an entity’s
1484 | lifetime, including whether it has ended (even if the date is unknown).
1485 | """
1486 | type LifeSpan {
1487 | """
1488 | The start date of the entity’s life span.
1489 | """
1490 | begin: Date
1491 |
1492 | """
1493 | The end date of the entity’s life span.
1494 | """
1495 | end: Date
1496 |
1497 | """
1498 | Whether or not the entity’s life span has ended.
1499 | """
1500 | ended: Boolean
1501 | }
1502 |
1503 | """
1504 | Language code, optionally with country and encoding.
1505 | """
1506 | scalar Locale
1507 |
1508 | """
1509 | A lookup of an individual MusicBrainz entity by its MBID.
1510 | """
1511 | type LookupQuery {
1512 | """
1513 | Look up a specific area by its MBID.
1514 | """
1515 | area(
1516 | """
1517 | The MBID of the entity.
1518 | """
1519 | mbid: MBID!
1520 | ): Area
1521 |
1522 | """
1523 | Look up a specific artist by its MBID.
1524 | """
1525 | artist(
1526 | """
1527 | The MBID of the entity.
1528 | """
1529 | mbid: MBID!
1530 | ): Artist
1531 |
1532 | """
1533 | Look up a specific collection by its MBID.
1534 | """
1535 | collection(
1536 | """
1537 | The MBID of the entity.
1538 | """
1539 | mbid: MBID!
1540 | ): Collection
1541 |
1542 | """
1543 | Look up a specific physical disc by its disc ID.
1544 | """
1545 | disc(
1546 | """
1547 | The [disc ID](https://musicbrainz.org/doc/Disc_ID)
1548 | of the disc.
1549 | """
1550 | discID: DiscID!
1551 | ): Disc
1552 |
1553 | """
1554 | Look up a specific event by its MBID.
1555 | """
1556 | event(
1557 | """
1558 | The MBID of the entity.
1559 | """
1560 | mbid: MBID!
1561 | ): Event
1562 |
1563 | """
1564 | Look up a specific instrument by its MBID.
1565 | """
1566 | instrument(
1567 | """
1568 | The MBID of the entity.
1569 | """
1570 | mbid: MBID!
1571 | ): Instrument
1572 |
1573 | """
1574 | Look up a specific label by its MBID.
1575 | """
1576 | label(
1577 | """
1578 | The MBID of the entity.
1579 | """
1580 | mbid: MBID!
1581 | ): Label
1582 |
1583 | """
1584 | Look up a specific place by its MBID.
1585 | """
1586 | place(
1587 | """
1588 | The MBID of the entity.
1589 | """
1590 | mbid: MBID!
1591 | ): Place
1592 |
1593 | """
1594 | Look up a specific recording by its MBID.
1595 | """
1596 | recording(
1597 | """
1598 | The MBID of the entity.
1599 | """
1600 | mbid: MBID!
1601 | ): Recording
1602 |
1603 | """
1604 | Look up a specific release by its MBID.
1605 | """
1606 | release(
1607 | """
1608 | The MBID of the entity.
1609 | """
1610 | mbid: MBID!
1611 | ): Release
1612 |
1613 | """
1614 | Look up a specific release group by its MBID.
1615 | """
1616 | releaseGroup(
1617 | """
1618 | The MBID of the entity.
1619 | """
1620 | mbid: MBID!
1621 | ): ReleaseGroup
1622 |
1623 | """
1624 | Look up a specific series by its MBID.
1625 | """
1626 | series(
1627 | """
1628 | The MBID of the entity.
1629 | """
1630 | mbid: MBID!
1631 | ): Series
1632 |
1633 | """
1634 | Look up a specific URL by its MBID.
1635 | """
1636 | url(
1637 | """
1638 | The MBID of the entity.
1639 | """
1640 | mbid: MBID
1641 |
1642 | """
1643 | The web address of the URL entity to look up.
1644 | """
1645 | resource: URLString
1646 | ): URL
1647 |
1648 | """
1649 | Look up a specific work by its MBID.
1650 | """
1651 | work(
1652 | """
1653 | The MBID of the entity.
1654 | """
1655 | mbid: MBID!
1656 | ): Work
1657 | }
1658 |
1659 | """
1660 | The MBID scalar represents MusicBrainz identifiers, which are
1661 | 36-character UUIDs.
1662 | """
1663 | scalar MBID
1664 |
1665 | """
1666 | A medium is the actual physical medium the audio content is
1667 | stored upon. This means that each CD in a multi-disc release will be entered as
1668 | separate mediums within the release, and that both sides of a vinyl record or
1669 | cassette will exist on one medium. Mediums have a format (e.g. CD, DVD, vinyl,
1670 | cassette) and can optionally also have a title.
1671 | """
1672 | type Medium {
1673 | """
1674 | The title of this particular medium.
1675 | """
1676 | title: String
1677 |
1678 | """
1679 | The [format](https://musicbrainz.org/doc/Release/Format) of
1680 | the medium (e.g. CD, DVD, vinyl, cassette).
1681 | """
1682 | format: String
1683 |
1684 | """
1685 | The MBID associated with the value of the `format`
1686 | field.
1687 | """
1688 | formatID: MBID
1689 |
1690 | """
1691 | The order of this medium in the release (for example, in a
1692 | multi-disc release).
1693 | """
1694 | position: Int
1695 |
1696 | """
1697 | The number of audio tracks on this medium.
1698 | """
1699 | trackCount: Int
1700 |
1701 | """
1702 | A list of physical discs and their disc IDs for this medium.
1703 | """
1704 | discs: [Disc]
1705 |
1706 | """
1707 | The list of tracks on the given media.
1708 | """
1709 | tracks: [Track]
1710 | }
1711 |
1712 | """
1713 | An object with an ID
1714 | """
1715 | interface Node {
1716 | """
1717 | The id of the object.
1718 | """
1719 | id: ID!
1720 | }
1721 |
1722 | """
1723 | Information about pagination in a connection.
1724 | """
1725 | type PageInfo {
1726 | """
1727 | When paginating forwards, are there more items?
1728 | """
1729 | hasNextPage: Boolean!
1730 |
1731 | """
1732 | When paginating backwards, are there more items?
1733 | """
1734 | hasPreviousPage: Boolean!
1735 |
1736 | """
1737 | When paginating backwards, the cursor to continue.
1738 | """
1739 | startCursor: String
1740 |
1741 | """
1742 | When paginating forwards, the cursor to continue.
1743 | """
1744 | endCursor: String
1745 | }
1746 |
1747 | """
1748 | A [place](https://musicbrainz.org/doc/Place) is a venue, studio,
1749 | or other place where music is performed, recorded, engineered, etc.
1750 | """
1751 | type Place implements Node & Entity {
1752 | """
1753 | The ID of an object
1754 | """
1755 | id: ID!
1756 |
1757 | """
1758 | The MBID of the entity.
1759 | """
1760 | mbid: MBID!
1761 |
1762 | """
1763 | The official name of the entity.
1764 | """
1765 | name: String
1766 |
1767 | """
1768 | A comment used to help distinguish identically named entitites.
1769 | """
1770 | disambiguation: String
1771 |
1772 | """
1773 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
1774 | alternate names or misspellings.
1775 | """
1776 | aliases: [Alias]
1777 |
1778 | """
1779 | The address describes the location of the place using the
1780 | standard addressing format for the country it is located in.
1781 | """
1782 | address: String
1783 |
1784 | """
1785 | The area entity representing the area, such as the city, in
1786 | which the place is located.
1787 | """
1788 | area: Area
1789 |
1790 | """
1791 | The geographic coordinates of the place.
1792 | """
1793 | coordinates: Coordinates
1794 |
1795 | """
1796 | The begin and end dates of the entity’s existence. Its exact
1797 | meaning depends on the type of entity.
1798 | """
1799 | lifeSpan: LifeSpan
1800 |
1801 | """
1802 | The type categorises the place based on its primary
1803 | function.
1804 | """
1805 | type: String
1806 |
1807 | """
1808 | The MBID associated with the value of the `type`
1809 | field.
1810 | """
1811 | typeID: MBID
1812 |
1813 | """
1814 | A list of events linked to this entity.
1815 | """
1816 | events(after: String, first: Int): EventConnection
1817 |
1818 | """
1819 | Relationships between this entity and other entitites.
1820 | """
1821 | relationships: Relationships
1822 |
1823 | """
1824 | A list of collections containing this entity.
1825 | """
1826 | collections(after: String, first: Int): CollectionConnection
1827 |
1828 | """
1829 | A list of tags linked to this entity.
1830 | """
1831 | tags(after: String, first: Int): TagConnection
1832 | }
1833 |
1834 | """
1835 | A connection to a list of items.
1836 | """
1837 | type PlaceConnection {
1838 | """
1839 | Information to aid in pagination.
1840 | """
1841 | pageInfo: PageInfo!
1842 |
1843 | """
1844 | A list of edges.
1845 | """
1846 | edges: [PlaceEdge]
1847 |
1848 | """
1849 | A list of nodes in the connection (without going through the
1850 | `edges` field).
1851 | """
1852 | nodes: [Place]
1853 |
1854 | """
1855 | A count of the total number of items in this connection,
1856 | ignoring pagination.
1857 | """
1858 | totalCount: Int
1859 | }
1860 |
1861 | """
1862 | An edge in a connection.
1863 | """
1864 | type PlaceEdge {
1865 | """
1866 | The item at the end of the edge
1867 | """
1868 | node: Place
1869 |
1870 | """
1871 | A cursor for use in pagination
1872 | """
1873 | cursor: String!
1874 |
1875 | """
1876 | The relevancy score (0–100) assigned by the search engine, if
1877 | these results were found through a search.
1878 | """
1879 | score: Int
1880 | }
1881 |
1882 | """
1883 | The query root, from which multiple types of MusicBrainz
1884 | requests can be made.
1885 | """
1886 | type Query {
1887 | """
1888 | Perform a lookup of a MusicBrainz entity by its MBID.
1889 | """
1890 | lookup: LookupQuery
1891 |
1892 | """
1893 | Browse all MusicBrainz entities directly linked to another entity.
1894 | """
1895 | browse: BrowseQuery
1896 |
1897 | """
1898 | Search for MusicBrainz entities using Lucene query syntax.
1899 | """
1900 | search: SearchQuery
1901 |
1902 | """
1903 | Fetches an object given its ID
1904 | """
1905 | node(
1906 | """
1907 | The ID of an object
1908 | """
1909 | id: ID!
1910 | ): Node
1911 | }
1912 |
1913 | """
1914 | [Ratings](https://musicbrainz.org/doc/Rating_System) allow users
1915 | to rate MusicBrainz entities. User may assign a value between 1 and 5; these
1916 | values are then aggregated by the server to compute an average community rating
1917 | for the entity.
1918 | """
1919 | type Rating {
1920 | """
1921 | The number of votes that have contributed to the rating.
1922 | """
1923 | voteCount: Int!
1924 |
1925 | """
1926 | The average rating value based on the aggregated votes.
1927 | """
1928 | value: Float
1929 | }
1930 |
1931 | """
1932 | A [recording](https://musicbrainz.org/doc/Recording) is an
1933 | entity in MusicBrainz which can be linked to tracks on releases. Each track must
1934 | always be associated with a single recording, but a recording can be linked to
1935 | any number of tracks.
1936 |
1937 | A recording represents distinct audio that has been used to produce at least one
1938 | released track through copying or mastering. A recording itself is never
1939 | produced solely through copying or mastering.
1940 |
1941 | Generally, the audio represented by a recording corresponds to the audio at a
1942 | stage in the production process before any final mastering but after any editing
1943 | or mixing.
1944 | """
1945 | type Recording implements Node & Entity {
1946 | """
1947 | The ID of an object
1948 | """
1949 | id: ID!
1950 |
1951 | """
1952 | The MBID of the entity.
1953 | """
1954 | mbid: MBID!
1955 |
1956 | """
1957 | The official title of the entity.
1958 | """
1959 | title: String
1960 |
1961 | """
1962 | A comment used to help distinguish identically named entitites.
1963 | """
1964 | disambiguation: String
1965 |
1966 | """
1967 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
1968 | alternate names or misspellings.
1969 | """
1970 | aliases: [Alias]
1971 |
1972 | """
1973 | The main credited artist(s).
1974 | """
1975 | artistCredit: [ArtistCredit]
1976 | @deprecated(
1977 | reason: "The `artistCredit` field has been renamed to\n`artistCredits`, since it is a list of credits and is referred to in the\nplural form throughout the MusicBrainz documentation. This field is deprecated\nand will be removed in a major release in the future. Use the equivalent\n`artistCredits` field."
1978 | )
1979 |
1980 | """
1981 | The main credited artist(s).
1982 | """
1983 | artistCredits: [ArtistCredit]
1984 |
1985 | """
1986 | A list of [International Standard Recording Codes](https://musicbrainz.org/doc/ISRC)
1987 | (ISRCs) for this recording.
1988 | """
1989 | isrcs: [ISRC]
1990 |
1991 | """
1992 | An approximation to the length of the recording, calculated
1993 | from the lengths of the tracks using it.
1994 | """
1995 | length: Duration
1996 |
1997 | """
1998 | Whether this is a video recording.
1999 | """
2000 | video: Boolean
2001 |
2002 | """
2003 | A list of artists linked to this entity.
2004 | """
2005 | artists(after: String, first: Int): ArtistConnection
2006 |
2007 | """
2008 | A list of releases linked to this entity.
2009 | """
2010 | releases(
2011 | """
2012 | Filter by one or more release group types.
2013 | """
2014 | type: [ReleaseGroupType]
2015 |
2016 | """
2017 | Filter by one or more release statuses.
2018 | """
2019 | status: [ReleaseStatus]
2020 | after: String
2021 | first: Int
2022 | ): ReleaseConnection
2023 |
2024 | """
2025 | Relationships between this entity and other entitites.
2026 | """
2027 | relationships: Relationships
2028 |
2029 | """
2030 | A list of collections containing this entity.
2031 | """
2032 | collections(after: String, first: Int): CollectionConnection
2033 |
2034 | """
2035 | The rating users have given to this entity.
2036 | """
2037 | rating: Rating
2038 |
2039 | """
2040 | A list of tags linked to this entity.
2041 | """
2042 | tags(after: String, first: Int): TagConnection
2043 | }
2044 |
2045 | """
2046 | A connection to a list of items.
2047 | """
2048 | type RecordingConnection {
2049 | """
2050 | Information to aid in pagination.
2051 | """
2052 | pageInfo: PageInfo!
2053 |
2054 | """
2055 | A list of edges.
2056 | """
2057 | edges: [RecordingEdge]
2058 |
2059 | """
2060 | A list of nodes in the connection (without going through the
2061 | `edges` field).
2062 | """
2063 | nodes: [Recording]
2064 |
2065 | """
2066 | A count of the total number of items in this connection,
2067 | ignoring pagination.
2068 | """
2069 | totalCount: Int
2070 | }
2071 |
2072 | """
2073 | An edge in a connection.
2074 | """
2075 | type RecordingEdge {
2076 | """
2077 | The item at the end of the edge
2078 | """
2079 | node: Recording
2080 |
2081 | """
2082 | A cursor for use in pagination
2083 | """
2084 | cursor: String!
2085 |
2086 | """
2087 | The relevancy score (0–100) assigned by the search engine, if
2088 | these results were found through a search.
2089 | """
2090 | score: Int
2091 | }
2092 |
2093 | """
2094 | [Relationships](https://musicbrainz.org/doc/Relationships) are a
2095 | way to represent all the different ways in which entities are connected to each
2096 | other and to URLs outside MusicBrainz.
2097 | """
2098 | type Relationship {
2099 | """
2100 | The target entity.
2101 | """
2102 | target: Entity!
2103 |
2104 | """
2105 | The direction of the relationship.
2106 | """
2107 | direction: String!
2108 |
2109 | """
2110 | The type of entity on the receiving end of the relationship.
2111 | """
2112 | targetType: String!
2113 |
2114 | """
2115 | How the source entity was actually credited, if different
2116 | from its main (performance) name.
2117 | """
2118 | sourceCredit: String
2119 |
2120 | """
2121 | How the target entity was actually credited, if different
2122 | from its main (performance) name.
2123 | """
2124 | targetCredit: String
2125 |
2126 | """
2127 | The date on which the relationship became applicable.
2128 | """
2129 | begin: Date
2130 |
2131 | """
2132 | The date on which the relationship became no longer applicable.
2133 | """
2134 | end: Date
2135 |
2136 | """
2137 | Whether the relationship still applies.
2138 | """
2139 | ended: Boolean
2140 |
2141 | """
2142 | Attributes which modify the relationship. There is a [list
2143 | of all attributes](https://musicbrainz.org/relationship-attributes), but the
2144 | attributes which are available, and how they should be used, depends on the
2145 | relationship type.
2146 | """
2147 | attributes: [String]
2148 |
2149 | """
2150 | The type of relationship.
2151 | """
2152 | type: String
2153 |
2154 | """
2155 | The MBID associated with the value of the `type`
2156 | field.
2157 | """
2158 | typeID: MBID
2159 | }
2160 |
2161 | """
2162 | A connection to a list of items.
2163 | """
2164 | type RelationshipConnection {
2165 | """
2166 | Information to aid in pagination.
2167 | """
2168 | pageInfo: PageInfo!
2169 |
2170 | """
2171 | A list of edges.
2172 | """
2173 | edges: [RelationshipEdge]
2174 |
2175 | """
2176 | A list of nodes in the connection (without going through the
2177 | `edges` field).
2178 | """
2179 | nodes: [Relationship]
2180 |
2181 | """
2182 | A count of the total number of items in this connection,
2183 | ignoring pagination.
2184 | """
2185 | totalCount: Int
2186 | }
2187 |
2188 | """
2189 | An edge in a connection.
2190 | """
2191 | type RelationshipEdge {
2192 | """
2193 | The item at the end of the edge
2194 | """
2195 | node: Relationship
2196 |
2197 | """
2198 | A cursor for use in pagination
2199 | """
2200 | cursor: String!
2201 |
2202 | """
2203 | The relevancy score (0–100) assigned by the search engine, if
2204 | these results were found through a search.
2205 | """
2206 | score: Int
2207 | }
2208 |
2209 | """
2210 | Lists of entity relationships for each entity type.
2211 | """
2212 | type Relationships {
2213 | """
2214 | A list of relationships between these two entity types.
2215 | """
2216 | areas(
2217 | """
2218 | Filter by the relationship direction.
2219 | """
2220 | direction: String
2221 |
2222 | """
2223 | Filter by the relationship type.
2224 | """
2225 | type: String
2226 |
2227 | """
2228 | The MBID associated with the value of the `type`
2229 | field.
2230 | """
2231 | typeID: MBID
2232 | after: String
2233 | first: Int
2234 | before: String
2235 | last: Int
2236 | ): RelationshipConnection
2237 |
2238 | """
2239 | A list of relationships between these two entity types.
2240 | """
2241 | artists(
2242 | """
2243 | Filter by the relationship direction.
2244 | """
2245 | direction: String
2246 |
2247 | """
2248 | Filter by the relationship type.
2249 | """
2250 | type: String
2251 |
2252 | """
2253 | The MBID associated with the value of the `type`
2254 | field.
2255 | """
2256 | typeID: MBID
2257 | after: String
2258 | first: Int
2259 | before: String
2260 | last: Int
2261 | ): RelationshipConnection
2262 |
2263 | """
2264 | A list of relationships between these two entity types.
2265 | """
2266 | events(
2267 | """
2268 | Filter by the relationship direction.
2269 | """
2270 | direction: String
2271 |
2272 | """
2273 | Filter by the relationship type.
2274 | """
2275 | type: String
2276 |
2277 | """
2278 | The MBID associated with the value of the `type`
2279 | field.
2280 | """
2281 | typeID: MBID
2282 | after: String
2283 | first: Int
2284 | before: String
2285 | last: Int
2286 | ): RelationshipConnection
2287 |
2288 | """
2289 | A list of relationships between these two entity types.
2290 | """
2291 | instruments(
2292 | """
2293 | Filter by the relationship direction.
2294 | """
2295 | direction: String
2296 |
2297 | """
2298 | Filter by the relationship type.
2299 | """
2300 | type: String
2301 |
2302 | """
2303 | The MBID associated with the value of the `type`
2304 | field.
2305 | """
2306 | typeID: MBID
2307 | after: String
2308 | first: Int
2309 | before: String
2310 | last: Int
2311 | ): RelationshipConnection
2312 |
2313 | """
2314 | A list of relationships between these two entity types.
2315 | """
2316 | labels(
2317 | """
2318 | Filter by the relationship direction.
2319 | """
2320 | direction: String
2321 |
2322 | """
2323 | Filter by the relationship type.
2324 | """
2325 | type: String
2326 |
2327 | """
2328 | The MBID associated with the value of the `type`
2329 | field.
2330 | """
2331 | typeID: MBID
2332 | after: String
2333 | first: Int
2334 | before: String
2335 | last: Int
2336 | ): RelationshipConnection
2337 |
2338 | """
2339 | A list of relationships between these two entity types.
2340 | """
2341 | places(
2342 | """
2343 | Filter by the relationship direction.
2344 | """
2345 | direction: String
2346 |
2347 | """
2348 | Filter by the relationship type.
2349 | """
2350 | type: String
2351 |
2352 | """
2353 | The MBID associated with the value of the `type`
2354 | field.
2355 | """
2356 | typeID: MBID
2357 | after: String
2358 | first: Int
2359 | before: String
2360 | last: Int
2361 | ): RelationshipConnection
2362 |
2363 | """
2364 | A list of relationships between these two entity types.
2365 | """
2366 | recordings(
2367 | """
2368 | Filter by the relationship direction.
2369 | """
2370 | direction: String
2371 |
2372 | """
2373 | Filter by the relationship type.
2374 | """
2375 | type: String
2376 |
2377 | """
2378 | The MBID associated with the value of the `type`
2379 | field.
2380 | """
2381 | typeID: MBID
2382 | after: String
2383 | first: Int
2384 | before: String
2385 | last: Int
2386 | ): RelationshipConnection
2387 |
2388 | """
2389 | A list of relationships between these two entity types.
2390 | """
2391 | releases(
2392 | """
2393 | Filter by the relationship direction.
2394 | """
2395 | direction: String
2396 |
2397 | """
2398 | Filter by the relationship type.
2399 | """
2400 | type: String
2401 |
2402 | """
2403 | The MBID associated with the value of the `type`
2404 | field.
2405 | """
2406 | typeID: MBID
2407 | after: String
2408 | first: Int
2409 | before: String
2410 | last: Int
2411 | ): RelationshipConnection
2412 |
2413 | """
2414 | A list of relationships between these two entity types.
2415 | """
2416 | releaseGroups(
2417 | """
2418 | Filter by the relationship direction.
2419 | """
2420 | direction: String
2421 |
2422 | """
2423 | Filter by the relationship type.
2424 | """
2425 | type: String
2426 |
2427 | """
2428 | The MBID associated with the value of the `type`
2429 | field.
2430 | """
2431 | typeID: MBID
2432 | after: String
2433 | first: Int
2434 | before: String
2435 | last: Int
2436 | ): RelationshipConnection
2437 |
2438 | """
2439 | A list of relationships between these two entity types.
2440 | """
2441 | series(
2442 | """
2443 | Filter by the relationship direction.
2444 | """
2445 | direction: String
2446 |
2447 | """
2448 | Filter by the relationship type.
2449 | """
2450 | type: String
2451 |
2452 | """
2453 | The MBID associated with the value of the `type`
2454 | field.
2455 | """
2456 | typeID: MBID
2457 | after: String
2458 | first: Int
2459 | before: String
2460 | last: Int
2461 | ): RelationshipConnection
2462 |
2463 | """
2464 | A list of relationships between these two entity types.
2465 | """
2466 | urls(
2467 | """
2468 | Filter by the relationship direction.
2469 | """
2470 | direction: String
2471 |
2472 | """
2473 | Filter by the relationship type.
2474 | """
2475 | type: String
2476 |
2477 | """
2478 | The MBID associated with the value of the `type`
2479 | field.
2480 | """
2481 | typeID: MBID
2482 | after: String
2483 | first: Int
2484 | before: String
2485 | last: Int
2486 | ): RelationshipConnection
2487 |
2488 | """
2489 | A list of relationships between these two entity types.
2490 | """
2491 | works(
2492 | """
2493 | Filter by the relationship direction.
2494 | """
2495 | direction: String
2496 |
2497 | """
2498 | Filter by the relationship type.
2499 | """
2500 | type: String
2501 |
2502 | """
2503 | The MBID associated with the value of the `type`
2504 | field.
2505 | """
2506 | typeID: MBID
2507 | after: String
2508 | first: Int
2509 | before: String
2510 | last: Int
2511 | ): RelationshipConnection
2512 | }
2513 |
2514 | """
2515 | A [release](https://musicbrainz.org/doc/Release) represents the
2516 | unique release (i.e. issuing) of a product on a specific date with specific
2517 | release information such as the country, label, barcode, packaging, etc. If you
2518 | walk into a store and purchase an album or single, they’re each represented in
2519 | MusicBrainz as one release.
2520 | """
2521 | type Release implements Node & Entity {
2522 | """
2523 | The ID of an object
2524 | """
2525 | id: ID!
2526 |
2527 | """
2528 | The MBID of the entity.
2529 | """
2530 | mbid: MBID!
2531 |
2532 | """
2533 | The official title of the entity.
2534 | """
2535 | title: String
2536 |
2537 | """
2538 | A comment used to help distinguish identically named entitites.
2539 | """
2540 | disambiguation: String
2541 |
2542 | """
2543 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
2544 | alternate names or misspellings.
2545 | """
2546 | aliases: [Alias]
2547 |
2548 | """
2549 | The main credited artist(s).
2550 | """
2551 | artistCredit: [ArtistCredit]
2552 | @deprecated(
2553 | reason: "The `artistCredit` field has been renamed to\n`artistCredits`, since it is a list of credits and is referred to in the\nplural form throughout the MusicBrainz documentation. This field is deprecated\nand will be removed in a major release in the future. Use the equivalent\n`artistCredits` field."
2554 | )
2555 |
2556 | """
2557 | The main credited artist(s).
2558 | """
2559 | artistCredits: [ArtistCredit]
2560 |
2561 | """
2562 | The release events for this release.
2563 | """
2564 | releaseEvents: [ReleaseEvent]
2565 |
2566 | """
2567 | The [release date](https://musicbrainz.org/doc/Release/Date)
2568 | is the date in which a release was made available through some sort of
2569 | distribution mechanism.
2570 | """
2571 | date: Date
2572 |
2573 | """
2574 | The country in which the release was issued.
2575 | """
2576 | country: String
2577 |
2578 | """
2579 | The [Amazon Standard Identification Number](https://musicbrainz.org/doc/ASIN)
2580 | of the release.
2581 | """
2582 | asin: ASIN
2583 |
2584 | """
2585 | The [barcode](https://en.wikipedia.org/wiki/Barcode), if the
2586 | release has one. The most common types found on releases are 12-digit
2587 | [UPCs](https://en.wikipedia.org/wiki/Universal_Product_Code) and 13-digit
2588 | [EANs](https://en.wikipedia.org/wiki/International_Article_Number).
2589 | """
2590 | barcode: String
2591 |
2592 | """
2593 | The status describes how “official” a release is.
2594 | """
2595 | status: ReleaseStatus
2596 |
2597 | """
2598 | The MBID associated with the value of the `status`
2599 | field.
2600 | """
2601 | statusID: MBID
2602 |
2603 | """
2604 | The physical packaging that accompanies the release. See
2605 | the [list of packaging](https://musicbrainz.org/doc/Release/Packaging) for more
2606 | information.
2607 | """
2608 | packaging: String
2609 |
2610 | """
2611 | The MBID associated with the value of the `packaging`
2612 | field.
2613 | """
2614 | packagingID: MBID
2615 |
2616 | """
2617 | Data quality indicates how good the data for a release is.
2618 | It is not a mark of how good or bad the music itself is – for that, use
2619 | [ratings](https://musicbrainz.org/doc/Rating_System).
2620 | """
2621 | quality: String
2622 |
2623 | """
2624 | The media on which the release was distributed.
2625 | """
2626 | media: [Medium]
2627 |
2628 | """
2629 | A list of artists linked to this entity.
2630 | """
2631 | artists(after: String, first: Int): ArtistConnection
2632 |
2633 | """
2634 | A list of labels linked to this entity.
2635 | """
2636 | labels(after: String, first: Int): LabelConnection
2637 |
2638 | """
2639 | A list of recordings linked to this entity.
2640 | """
2641 | recordings(after: String, first: Int): RecordingConnection
2642 |
2643 | """
2644 | A list of release groups linked to this entity.
2645 | """
2646 | releaseGroups(
2647 | """
2648 | Filter by one or more release group types.
2649 | """
2650 | type: [ReleaseGroupType]
2651 | after: String
2652 | first: Int
2653 | ): ReleaseGroupConnection
2654 |
2655 | """
2656 | Relationships between this entity and other entitites.
2657 | """
2658 | relationships: Relationships
2659 |
2660 | """
2661 | A list of collections containing this entity.
2662 | """
2663 | collections(after: String, first: Int): CollectionConnection
2664 |
2665 | """
2666 | A list of tags linked to this entity.
2667 | """
2668 | tags(after: String, first: Int): TagConnection
2669 | }
2670 |
2671 | """
2672 | A connection to a list of items.
2673 | """
2674 | type ReleaseConnection {
2675 | """
2676 | Information to aid in pagination.
2677 | """
2678 | pageInfo: PageInfo!
2679 |
2680 | """
2681 | A list of edges.
2682 | """
2683 | edges: [ReleaseEdge]
2684 |
2685 | """
2686 | A list of nodes in the connection (without going through the
2687 | `edges` field).
2688 | """
2689 | nodes: [Release]
2690 |
2691 | """
2692 | A count of the total number of items in this connection,
2693 | ignoring pagination.
2694 | """
2695 | totalCount: Int
2696 | }
2697 |
2698 | """
2699 | An edge in a connection.
2700 | """
2701 | type ReleaseEdge {
2702 | """
2703 | The item at the end of the edge
2704 | """
2705 | node: Release
2706 |
2707 | """
2708 | A cursor for use in pagination
2709 | """
2710 | cursor: String!
2711 |
2712 | """
2713 | The relevancy score (0–100) assigned by the search engine, if
2714 | these results were found through a search.
2715 | """
2716 | score: Int
2717 | }
2718 |
2719 | """
2720 | The date on which a release was issued in a country/region with
2721 | a particular label, catalog number, barcode, and format.
2722 | """
2723 | type ReleaseEvent {
2724 | area: Area
2725 | date: Date
2726 | }
2727 |
2728 | """
2729 | A [release group](https://musicbrainz.org/doc/Release_Group) is
2730 | used to group several different releases into a single logical entity. Every
2731 | release belongs to one, and only one release group.
2732 |
2733 | Both release groups and releases are “albums” in a general sense, but with an
2734 | important difference: a release is something you can buy as media such as a CD
2735 | or a vinyl record, while a release group embraces the overall concept of an
2736 | album – it doesn’t matter how many CDs or editions/versions it had.
2737 | """
2738 | type ReleaseGroup implements Node & Entity {
2739 | """
2740 | The ID of an object
2741 | """
2742 | id: ID!
2743 |
2744 | """
2745 | The MBID of the entity.
2746 | """
2747 | mbid: MBID!
2748 |
2749 | """
2750 | The official title of the entity.
2751 | """
2752 | title: String
2753 |
2754 | """
2755 | A comment used to help distinguish identically named entitites.
2756 | """
2757 | disambiguation: String
2758 |
2759 | """
2760 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
2761 | alternate names or misspellings.
2762 | """
2763 | aliases: [Alias]
2764 |
2765 | """
2766 | The main credited artist(s).
2767 | """
2768 | artistCredit: [ArtistCredit]
2769 | @deprecated(
2770 | reason: "The `artistCredit` field has been renamed to\n`artistCredits`, since it is a list of credits and is referred to in the\nplural form throughout the MusicBrainz documentation. This field is deprecated\nand will be removed in a major release in the future. Use the equivalent\n`artistCredits` field."
2771 | )
2772 |
2773 | """
2774 | The main credited artist(s).
2775 | """
2776 | artistCredits: [ArtistCredit]
2777 |
2778 | """
2779 | The date of the earliest release in the group.
2780 | """
2781 | firstReleaseDate: Date
2782 |
2783 | """
2784 | The [type](https://musicbrainz.org/doc/Release_Group/Type)
2785 | of a release group describes what kind of releases the release group represents,
2786 | e.g. album, single, soundtrack, compilation, etc. A release group can have a
2787 | “main” type and an unspecified number of additional types.
2788 | """
2789 | primaryType: ReleaseGroupType
2790 |
2791 | """
2792 | The MBID associated with the value of the `primaryType`
2793 | field.
2794 | """
2795 | primaryTypeID: MBID
2796 |
2797 | """
2798 | Additional [types](https://musicbrainz.org/doc/Release_Group/Type)
2799 | that apply to this release group.
2800 | """
2801 | secondaryTypes: [ReleaseGroupType]
2802 |
2803 | """
2804 | The MBIDs associated with the values of the `secondaryTypes`
2805 | field.
2806 | """
2807 | secondaryTypeIDs: [MBID]
2808 |
2809 | """
2810 | A list of artists linked to this entity.
2811 | """
2812 | artists(after: String, first: Int): ArtistConnection
2813 |
2814 | """
2815 | A list of releases linked to this entity.
2816 | """
2817 | releases(
2818 | """
2819 | Filter by one or more release group types.
2820 | """
2821 | type: [ReleaseGroupType]
2822 |
2823 | """
2824 | Filter by one or more release statuses.
2825 | """
2826 | status: [ReleaseStatus]
2827 | after: String
2828 | first: Int
2829 | ): ReleaseConnection
2830 |
2831 | """
2832 | Relationships between this entity and other entitites.
2833 | """
2834 | relationships: Relationships
2835 |
2836 | """
2837 | A list of collections containing this entity.
2838 | """
2839 | collections(after: String, first: Int): CollectionConnection
2840 |
2841 | """
2842 | The rating users have given to this entity.
2843 | """
2844 | rating: Rating
2845 |
2846 | """
2847 | A list of tags linked to this entity.
2848 | """
2849 | tags(after: String, first: Int): TagConnection
2850 | }
2851 |
2852 | """
2853 | A connection to a list of items.
2854 | """
2855 | type ReleaseGroupConnection {
2856 | """
2857 | Information to aid in pagination.
2858 | """
2859 | pageInfo: PageInfo!
2860 |
2861 | """
2862 | A list of edges.
2863 | """
2864 | edges: [ReleaseGroupEdge]
2865 |
2866 | """
2867 | A list of nodes in the connection (without going through the
2868 | `edges` field).
2869 | """
2870 | nodes: [ReleaseGroup]
2871 |
2872 | """
2873 | A count of the total number of items in this connection,
2874 | ignoring pagination.
2875 | """
2876 | totalCount: Int
2877 | }
2878 |
2879 | """
2880 | An edge in a connection.
2881 | """
2882 | type ReleaseGroupEdge {
2883 | """
2884 | The item at the end of the edge
2885 | """
2886 | node: ReleaseGroup
2887 |
2888 | """
2889 | A cursor for use in pagination
2890 | """
2891 | cursor: String!
2892 |
2893 | """
2894 | The relevancy score (0–100) assigned by the search engine, if
2895 | these results were found through a search.
2896 | """
2897 | score: Int
2898 | }
2899 |
2900 | """
2901 | A type used to describe release groups, e.g. album, single, EP,
2902 | etc.
2903 | """
2904 | enum ReleaseGroupType {
2905 | """
2906 | An album, perhaps better defined as a “Long Play” (LP)
2907 | release, generally consists of previously unreleased material (unless this type
2908 | is combined with secondary types which change that, such as “Compilation”). This
2909 | includes album re-issues, with or without bonus tracks.
2910 | """
2911 | ALBUM
2912 |
2913 | """
2914 | A single typically has one main song and possibly a handful
2915 | of additional tracks or remixes of the main track. A single is usually named
2916 | after its main song.
2917 | """
2918 | SINGLE
2919 |
2920 | """
2921 | An EP is a so-called “Extended Play” release and often
2922 | contains the letters EP in the title. Generally an EP will be shorter than a
2923 | full length release (an LP or “Long Play”) and the tracks are usually exclusive
2924 | to the EP, in other words the tracks don’t come from a previously issued
2925 | release. EP is fairly difficult to define; usually it should only be assumed
2926 | that a release is an EP if the artist defines it as such.
2927 | """
2928 | EP
2929 |
2930 | """
2931 | Any release that does not fit any of the other categories.
2932 | """
2933 | OTHER
2934 |
2935 | """
2936 | An episodic release that was originally broadcast via radio,
2937 | television, or the Internet, including podcasts.
2938 | """
2939 | BROADCAST
2940 |
2941 | """
2942 | A compilation is a collection of previously released tracks
2943 | by one or more artists.
2944 | """
2945 | COMPILATION
2946 |
2947 | """
2948 | A soundtrack is the musical score to a movie, TV series,
2949 | stage show, computer game, etc.
2950 | """
2951 | SOUNDTRACK
2952 |
2953 | """
2954 | A non-music spoken word release.
2955 | """
2956 | SPOKENWORD
2957 |
2958 | """
2959 | An interview release contains an interview, generally with
2960 | an artist.
2961 | """
2962 | INTERVIEW
2963 |
2964 | """
2965 | An audiobook is a book read by a narrator without music.
2966 | """
2967 | AUDIOBOOK
2968 |
2969 | """
2970 | A release that was recorded live.
2971 | """
2972 | LIVE
2973 |
2974 | """
2975 | A release that was (re)mixed from previously released
2976 | material.
2977 | """
2978 | REMIX
2979 |
2980 | """
2981 | A DJ-mix is a sequence of several recordings played one
2982 | after the other, each one modified so that they blend together into a continuous
2983 | flow of music. A DJ mix release requires that the recordings be modified in some
2984 | manner, and the DJ who does this modification is usually (although not always)
2985 | credited in a fairly prominent way.
2986 | """
2987 | DJMIX
2988 |
2989 | """
2990 | Promotional in nature (but not necessarily free), mixtapes
2991 | and street albums are often released by artists to promote new artists, or
2992 | upcoming studio albums by prominent artists. They are also sometimes used to
2993 | keep fans’ attention between studio releases and are most common in rap & hip
2994 | hop genres. They are often not sanctioned by the artist’s label, may lack proper
2995 | sample or song clearances and vary widely in production and recording quality.
2996 | While mixtapes are generally DJ-mixed, they are distinct from commercial DJ
2997 | mixes (which are usually deemed compilations) and are defined by having a
2998 | significant proportion of new material, including original production or
2999 | original vocals over top of other artists’ instrumentals. They are distinct from
3000 | demos in that they are designed for release directly to the public and fans, not
3001 | to labels.
3002 | """
3003 | MIXTAPE
3004 |
3005 | """
3006 | A release that was recorded for limited circulation or
3007 | reference use rather than for general public release.
3008 | """
3009 | DEMO
3010 |
3011 | """
3012 | A non-album track (special case).
3013 | """
3014 | NAT
3015 | }
3016 |
3017 | """
3018 | A type used to describe the status of releases, e.g. official,
3019 | bootleg, etc.
3020 | """
3021 | enum ReleaseStatus {
3022 | """
3023 | Any release officially sanctioned by the artist and/or their
3024 | record company. (Most releases will fit into this category.)
3025 | """
3026 | OFFICIAL
3027 |
3028 | """
3029 | A giveaway release or a release intended to promote an
3030 | upcoming official release, e.g. prerelease albums or releases included with a
3031 | magazine.
3032 | """
3033 | PROMOTION
3034 |
3035 | """
3036 | An unofficial/underground release that was not sanctioned by
3037 | the artist and/or the record company.
3038 | """
3039 | BOOTLEG
3040 |
3041 | """
3042 | A pseudo-release is a duplicate release for
3043 | translation/transliteration purposes.
3044 | """
3045 | PSEUDORELEASE
3046 | }
3047 |
3048 | """
3049 | A search for MusicBrainz entities using Lucene query syntax.
3050 | """
3051 | type SearchQuery {
3052 | """
3053 | Search for area entities matching the given query.
3054 | """
3055 | areas(
3056 | """
3057 | The query terms, in Lucene search syntax. See [examples
3058 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3059 | """
3060 | query: String!
3061 | after: String
3062 | first: Int
3063 | ): AreaConnection
3064 |
3065 | """
3066 | Search for artist entities matching the given query.
3067 | """
3068 | artists(
3069 | """
3070 | The query terms, in Lucene search syntax. See [examples
3071 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3072 | """
3073 | query: String!
3074 | after: String
3075 | first: Int
3076 | ): ArtistConnection
3077 |
3078 | """
3079 | Search for event entities matching the given query.
3080 | """
3081 | events(
3082 | """
3083 | The query terms, in Lucene search syntax. See [examples
3084 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3085 | """
3086 | query: String!
3087 | after: String
3088 | first: Int
3089 | ): EventConnection
3090 |
3091 | """
3092 | Search for instrument entities matching the given query.
3093 | """
3094 | instruments(
3095 | """
3096 | The query terms, in Lucene search syntax. See [examples
3097 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3098 | """
3099 | query: String!
3100 | after: String
3101 | first: Int
3102 | ): InstrumentConnection
3103 |
3104 | """
3105 | Search for label entities matching the given query.
3106 | """
3107 | labels(
3108 | """
3109 | The query terms, in Lucene search syntax. See [examples
3110 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3111 | """
3112 | query: String!
3113 | after: String
3114 | first: Int
3115 | ): LabelConnection
3116 |
3117 | """
3118 | Search for place entities matching the given query.
3119 | """
3120 | places(
3121 | """
3122 | The query terms, in Lucene search syntax. See [examples
3123 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3124 | """
3125 | query: String!
3126 | after: String
3127 | first: Int
3128 | ): PlaceConnection
3129 |
3130 | """
3131 | Search for recording entities matching the given query.
3132 | """
3133 | recordings(
3134 | """
3135 | The query terms, in Lucene search syntax. See [examples
3136 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3137 | """
3138 | query: String!
3139 | after: String
3140 | first: Int
3141 | ): RecordingConnection
3142 |
3143 | """
3144 | Search for release entities matching the given query.
3145 | """
3146 | releases(
3147 | """
3148 | The query terms, in Lucene search syntax. See [examples
3149 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3150 | """
3151 | query: String!
3152 | after: String
3153 | first: Int
3154 | ): ReleaseConnection
3155 |
3156 | """
3157 | Search for release group entities matching the given query.
3158 | """
3159 | releaseGroups(
3160 | """
3161 | The query terms, in Lucene search syntax. See [examples
3162 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3163 | """
3164 | query: String!
3165 | after: String
3166 | first: Int
3167 | ): ReleaseGroupConnection
3168 |
3169 | """
3170 | Search for series entities matching the given query.
3171 | """
3172 | series(
3173 | """
3174 | The query terms, in Lucene search syntax. See [examples
3175 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3176 | """
3177 | query: String!
3178 | after: String
3179 | first: Int
3180 | ): SeriesConnection
3181 |
3182 | """
3183 | Search for work entities matching the given query.
3184 | """
3185 | works(
3186 | """
3187 | The query terms, in Lucene search syntax. See [examples
3188 | and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).
3189 | """
3190 | query: String!
3191 | after: String
3192 | first: Int
3193 | ): WorkConnection
3194 | }
3195 |
3196 | """
3197 | A [series](https://musicbrainz.org/doc/Series) is a sequence of
3198 | separate release groups, releases, recordings, works or events with a common
3199 | theme.
3200 | """
3201 | type Series implements Node & Entity {
3202 | """
3203 | The ID of an object
3204 | """
3205 | id: ID!
3206 |
3207 | """
3208 | The MBID of the entity.
3209 | """
3210 | mbid: MBID!
3211 |
3212 | """
3213 | The official name of the entity.
3214 | """
3215 | name: String
3216 |
3217 | """
3218 | A comment used to help distinguish identically named entitites.
3219 | """
3220 | disambiguation: String
3221 |
3222 | """
3223 | The type primarily describes what type of entity the series
3224 | contains.
3225 | """
3226 | type: String
3227 |
3228 | """
3229 | The MBID associated with the value of the `type`
3230 | field.
3231 | """
3232 | typeID: MBID
3233 |
3234 | """
3235 | Relationships between this entity and other entitites.
3236 | """
3237 | relationships: Relationships
3238 |
3239 | """
3240 | A list of collections containing this entity.
3241 | """
3242 | collections(after: String, first: Int): CollectionConnection
3243 |
3244 | """
3245 | A list of tags linked to this entity.
3246 | """
3247 | tags(after: String, first: Int): TagConnection
3248 | }
3249 |
3250 | """
3251 | A connection to a list of items.
3252 | """
3253 | type SeriesConnection {
3254 | """
3255 | Information to aid in pagination.
3256 | """
3257 | pageInfo: PageInfo!
3258 |
3259 | """
3260 | A list of edges.
3261 | """
3262 | edges: [SeriesEdge]
3263 |
3264 | """
3265 | A list of nodes in the connection (without going through the
3266 | `edges` field).
3267 | """
3268 | nodes: [Series]
3269 |
3270 | """
3271 | A count of the total number of items in this connection,
3272 | ignoring pagination.
3273 | """
3274 | totalCount: Int
3275 | }
3276 |
3277 | """
3278 | An edge in a connection.
3279 | """
3280 | type SeriesEdge {
3281 | """
3282 | The item at the end of the edge
3283 | """
3284 | node: Series
3285 |
3286 | """
3287 | A cursor for use in pagination
3288 | """
3289 | cursor: String!
3290 |
3291 | """
3292 | The relevancy score (0–100) assigned by the search engine, if
3293 | these results were found through a search.
3294 | """
3295 | score: Int
3296 | }
3297 |
3298 | """
3299 | [Tags](https://musicbrainz.org/tags) are a way to mark entities
3300 | with extra information – for example, the genres that apply to an artist,
3301 | release, or recording.
3302 | """
3303 | type Tag {
3304 | """
3305 | The tag label.
3306 | """
3307 | name: String!
3308 |
3309 | """
3310 | How many times this tag has been applied to the entity.
3311 | """
3312 | count: Int
3313 | }
3314 |
3315 | """
3316 | A connection to a list of items.
3317 | """
3318 | type TagConnection {
3319 | """
3320 | Information to aid in pagination.
3321 | """
3322 | pageInfo: PageInfo!
3323 |
3324 | """
3325 | A list of edges.
3326 | """
3327 | edges: [TagEdge]
3328 |
3329 | """
3330 | A list of nodes in the connection (without going through the
3331 | `edges` field).
3332 | """
3333 | nodes: [Tag]
3334 |
3335 | """
3336 | A count of the total number of items in this connection,
3337 | ignoring pagination.
3338 | """
3339 | totalCount: Int
3340 | }
3341 |
3342 | """
3343 | An edge in a connection.
3344 | """
3345 | type TagEdge {
3346 | """
3347 | The item at the end of the edge
3348 | """
3349 | node: Tag
3350 |
3351 | """
3352 | A cursor for use in pagination
3353 | """
3354 | cursor: String!
3355 |
3356 | """
3357 | The relevancy score (0–100) assigned by the search engine, if
3358 | these results were found through a search.
3359 | """
3360 | score: Int
3361 | }
3362 |
3363 | """
3364 | A time of day, in 24-hour hh:mm notation.
3365 | """
3366 | scalar Time
3367 |
3368 | """
3369 | A track is the way a recording is represented on a particular
3370 | release (or, more exactly, on a particular medium). Every track has a title
3371 | (see the guidelines for titles) and is credited to one or more artists.
3372 | """
3373 | type Track implements Entity {
3374 | """
3375 | The MBID of the entity.
3376 | """
3377 | mbid: MBID!
3378 |
3379 | """
3380 | The official title of the entity.
3381 | """
3382 | title: String
3383 |
3384 | """
3385 | The track’s position on the overall release (including all
3386 | tracks from all discs).
3387 | """
3388 | position: Int
3389 |
3390 | """
3391 | The track number, which may include information about the
3392 | disc or side it appears on, e.g. “A1” or “B3”.
3393 | """
3394 | number: String
3395 |
3396 | """
3397 | The length of the track.
3398 | """
3399 | length: Duration
3400 |
3401 | """
3402 | The recording that appears on the track.
3403 | """
3404 | recording: Recording
3405 | }
3406 |
3407 | """
3408 | A [URL](https://musicbrainz.org/doc/URL) pointing to a resource
3409 | external to MusicBrainz, i.e. an official homepage, a site where music can be
3410 | acquired, an entry in another database, etc.
3411 | """
3412 | type URL implements Node & Entity {
3413 | """
3414 | The ID of an object
3415 | """
3416 | id: ID!
3417 |
3418 | """
3419 | The MBID of the entity.
3420 | """
3421 | mbid: MBID!
3422 |
3423 | """
3424 | The actual URL string.
3425 | """
3426 | resource: URLString!
3427 |
3428 | """
3429 | Relationships between this entity and other entitites.
3430 | """
3431 | relationships: Relationships
3432 | }
3433 |
3434 | """
3435 | A web address.
3436 | """
3437 | scalar URLString
3438 |
3439 | """
3440 | A [work](https://musicbrainz.org/doc/Work) is a distinct
3441 | intellectual or artistic creation, which can be expressed in the form of one or
3442 | more audio recordings.
3443 | """
3444 | type Work implements Node & Entity {
3445 | """
3446 | The ID of an object
3447 | """
3448 | id: ID!
3449 |
3450 | """
3451 | The MBID of the entity.
3452 | """
3453 | mbid: MBID!
3454 |
3455 | """
3456 | The official title of the entity.
3457 | """
3458 | title: String
3459 |
3460 | """
3461 | A comment used to help distinguish identically named entitites.
3462 | """
3463 | disambiguation: String
3464 |
3465 | """
3466 | [Aliases](https://musicbrainz.org/doc/Aliases) are used to store
3467 | alternate names or misspellings.
3468 | """
3469 | aliases: [Alias]
3470 |
3471 | """
3472 | A list of [ISWCs](https://musicbrainz.org/doc/ISWC) assigned
3473 | to the work by copyright collecting agencies.
3474 | """
3475 | iswcs: [String]
3476 |
3477 | """
3478 | The language in which the work was originally written.
3479 | """
3480 | language: String
3481 |
3482 | """
3483 | The type of work.
3484 | """
3485 | type: String
3486 |
3487 | """
3488 | The MBID associated with the value of the `type`
3489 | field.
3490 | """
3491 | typeID: MBID
3492 |
3493 | """
3494 | A list of artists linked to this entity.
3495 | """
3496 | artists(after: String, first: Int): ArtistConnection
3497 |
3498 | """
3499 | Relationships between this entity and other entitites.
3500 | """
3501 | relationships: Relationships
3502 |
3503 | """
3504 | A list of collections containing this entity.
3505 | """
3506 | collections(after: String, first: Int): CollectionConnection
3507 |
3508 | """
3509 | The rating users have given to this entity.
3510 | """
3511 | rating: Rating
3512 |
3513 | """
3514 | A list of tags linked to this entity.
3515 | """
3516 | tags(after: String, first: Int): TagConnection
3517 | }
3518 |
3519 | """
3520 | A connection to a list of items.
3521 | """
3522 | type WorkConnection {
3523 | """
3524 | Information to aid in pagination.
3525 | """
3526 | pageInfo: PageInfo!
3527 |
3528 | """
3529 | A list of edges.
3530 | """
3531 | edges: [WorkEdge]
3532 |
3533 | """
3534 | A list of nodes in the connection (without going through the
3535 | `edges` field).
3536 | """
3537 | nodes: [Work]
3538 |
3539 | """
3540 | A count of the total number of items in this connection,
3541 | ignoring pagination.
3542 | """
3543 | totalCount: Int
3544 | }
3545 |
3546 | """
3547 | An edge in a connection.
3548 | """
3549 | type WorkEdge {
3550 | """
3551 | The item at the end of the edge
3552 | """
3553 | node: Work
3554 |
3555 | """
3556 | A cursor for use in pagination
3557 | """
3558 | cursor: String!
3559 |
3560 | """
3561 | The relevancy score (0–100) assigned by the search engine, if
3562 | these results were found through a search.
3563 | """
3564 | score: Int
3565 | }
3566 |
--------------------------------------------------------------------------------
/test/fixtures/input-objects.graphql:
--------------------------------------------------------------------------------
1 | input MessageInput {
2 | content: String
3 | author: String
4 | }
5 |
6 | type Message {
7 | id: ID!
8 | content: String
9 | author: String
10 | }
11 |
12 | type Query {
13 | getMessage(id: ID!): Message
14 | }
15 |
16 | type Mutation {
17 | createMessage(input: MessageInput): Message
18 | updateMessage(id: ID!, input: MessageInput): Message
19 | }
20 |
21 | type Subscription {
22 | """
23 | Subscribe to new messages.
24 | """
25 | messageSent: Message
26 | }
27 |
--------------------------------------------------------------------------------
/test/fixtures/input-objects.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | Table of Contents
5 |
6 | * [Query](#query)
7 | * [Mutation](#mutation)
8 | * [Subscription](#subscription)
9 | * [Objects](#objects)
10 | * [Message](#message)
11 | * [Inputs](#inputs)
12 | * [MessageInput](#messageinput)
13 | * [Scalars](#scalars)
14 | * [Boolean](#boolean)
15 | * [ID](#id)
16 | * [String](#string)
17 |
18 |
19 |
20 | ## Query
21 |
22 |
23 |
24 | Field |
25 | Argument |
26 | Type |
27 | Description |
28 |
29 |
30 |
31 |
32 | getMessage |
33 | Message |
34 | |
35 |
36 |
37 | id |
38 | ID! |
39 | |
40 |
41 |
42 |
43 |
44 | ## Mutation
45 |
46 |
47 |
48 | Field |
49 | Argument |
50 | Type |
51 | Description |
52 |
53 |
54 |
55 |
56 | createMessage |
57 | Message |
58 | |
59 |
60 |
61 | input |
62 | MessageInput |
63 | |
64 |
65 |
66 | updateMessage |
67 | Message |
68 | |
69 |
70 |
71 | id |
72 | ID! |
73 | |
74 |
75 |
76 | input |
77 | MessageInput |
78 | |
79 |
80 |
81 |
82 |
83 | ## Subscription
84 |
85 |
86 |
87 | Field |
88 | Argument |
89 | Type |
90 | Description |
91 |
92 |
93 |
94 |
95 | messageSent |
96 | Message |
97 |
98 |
99 | Subscribe to new messages.
100 |
101 | |
102 |
103 |
104 |
105 |
106 | ## Objects
107 |
108 | ### Message
109 |
110 |
111 |
112 |
113 | Field |
114 | Argument |
115 | Type |
116 | Description |
117 |
118 |
119 |
120 |
121 | id |
122 | ID! |
123 | |
124 |
125 |
126 | content |
127 | String |
128 | |
129 |
130 |
131 | author |
132 | String |
133 | |
134 |
135 |
136 |
137 |
138 | ## Inputs
139 |
140 | ### MessageInput
141 |
142 |
143 |
144 |
145 | Field |
146 | Type |
147 | Description |
148 |
149 |
150 |
151 |
152 | content |
153 | String |
154 | |
155 |
156 |
157 | author |
158 | String |
159 | |
160 |
161 |
162 |
163 |
164 | ## Scalars
165 |
166 | ### Boolean
167 |
168 | The `Boolean` scalar type represents `true` or `false`.
169 |
170 | ### ID
171 |
172 | The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
173 |
174 | ### String
175 |
176 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
177 |
178 |
--------------------------------------------------------------------------------
/test/fixtures/no-toc.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | ## Query
5 |
6 |
7 |
8 | Field |
9 | Argument |
10 | Type |
11 | Description |
12 |
13 |
14 |
15 |
16 | getMessage |
17 | Message |
18 | |
19 |
20 |
21 | id |
22 | ID! |
23 | |
24 |
25 |
26 |
27 |
28 | ## Mutation
29 |
30 |
31 |
32 | Field |
33 | Argument |
34 | Type |
35 | Description |
36 |
37 |
38 |
39 |
40 | createMessage |
41 | Message |
42 | |
43 |
44 |
45 | input |
46 | MessageInput |
47 | |
48 |
49 |
50 | updateMessage |
51 | Message |
52 | |
53 |
54 |
55 | id |
56 | ID! |
57 | |
58 |
59 |
60 | input |
61 | MessageInput |
62 | |
63 |
64 |
65 |
66 |
67 | ## Subscription
68 |
69 |
70 |
71 | Field |
72 | Argument |
73 | Type |
74 | Description |
75 |
76 |
77 |
78 |
79 | messageSent |
80 | Message |
81 |
82 |
83 | Subscribe to new messages.
84 |
85 | |
86 |
87 |
88 |
89 |
90 | ## Objects
91 |
92 | ### Message
93 |
94 |
95 |
96 |
97 | Field |
98 | Argument |
99 | Type |
100 | Description |
101 |
102 |
103 |
104 |
105 | id |
106 | ID! |
107 | |
108 |
109 |
110 | content |
111 | String |
112 | |
113 |
114 |
115 | author |
116 | String |
117 | |
118 |
119 |
120 |
121 |
122 | ## Inputs
123 |
124 | ### MessageInput
125 |
126 |
127 |
128 |
129 | Field |
130 | Type |
131 | Description |
132 |
133 |
134 |
135 |
136 | content |
137 | String |
138 | |
139 |
140 |
141 | author |
142 | String |
143 | |
144 |
145 |
146 |
147 |
148 | ## Scalars
149 |
150 | ### Boolean
151 |
152 | The `Boolean` scalar type represents `true` or `false`.
153 |
154 | ### ID
155 |
156 | The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
157 |
158 | ### String
159 |
160 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
161 |
162 |
--------------------------------------------------------------------------------
/test/fixtures/toc-fields.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | Table of Contents
5 |
6 | * [Query](#query)
7 | * [getMessage](#query.getmessage)
8 | * [Mutation](#mutation)
9 | * [createMessage](#mutation.createmessage)
10 | * [updateMessage](#mutation.updatemessage)
11 | * [Subscription](#subscription)
12 | * [Objects](#objects)
13 | * [Message](#message)
14 | * [Inputs](#inputs)
15 | * [MessageInput](#messageinput)
16 | * [content](#messageinput.content)
17 | * [author](#messageinput.author)
18 | * [Scalars](#scalars)
19 | * [Boolean](#boolean)
20 | * [ID](#id)
21 | * [String](#string)
22 |
23 |
24 |
25 | ## Query
26 |
27 |
28 |
29 | Field |
30 | Argument |
31 | Type |
32 | Description |
33 |
34 |
35 |
36 |
37 | getMessage |
38 | Message |
39 | |
40 |
41 |
42 | id |
43 | ID! |
44 | |
45 |
46 |
47 |
48 |
49 | ## Mutation
50 |
51 |
52 |
53 | Field |
54 | Argument |
55 | Type |
56 | Description |
57 |
58 |
59 |
60 |
61 | createMessage |
62 | Message |
63 | |
64 |
65 |
66 | input |
67 | MessageInput |
68 | |
69 |
70 |
71 | updateMessage |
72 | Message |
73 | |
74 |
75 |
76 | id |
77 | ID! |
78 | |
79 |
80 |
81 | input |
82 | MessageInput |
83 | |
84 |
85 |
86 |
87 |
88 | ## Subscription
89 |
90 |
91 |
92 | Field |
93 | Argument |
94 | Type |
95 | Description |
96 |
97 |
98 |
99 |
100 | messageSent |
101 | Message |
102 |
103 |
104 | Subscribe to new messages.
105 |
106 | |
107 |
108 |
109 |
110 |
111 | ## Objects
112 |
113 | ### Message
114 |
115 |
116 |
117 |
118 | Field |
119 | Argument |
120 | Type |
121 | Description |
122 |
123 |
124 |
125 |
126 | id |
127 | ID! |
128 | |
129 |
130 |
131 | content |
132 | String |
133 | |
134 |
135 |
136 | author |
137 | String |
138 | |
139 |
140 |
141 |
142 |
143 | ## Inputs
144 |
145 | ### MessageInput
146 |
147 |
148 |
149 |
150 | Field |
151 | Type |
152 | Description |
153 |
154 |
155 |
156 |
157 | content |
158 | String |
159 | |
160 |
161 |
162 | author |
163 | String |
164 | |
165 |
166 |
167 |
168 |
169 | ## Scalars
170 |
171 | ### Boolean
172 |
173 | The `Boolean` scalar type represents `true` or `false`.
174 |
175 | ### ID
176 |
177 | The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
178 |
179 | ### String
180 |
181 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
182 |
183 |
--------------------------------------------------------------------------------
/test/fixtures/union-test-2.graphql:
--------------------------------------------------------------------------------
1 | type Query {
2 | mammals: [Mammal]
3 | }
4 |
5 | """
6 | *italic*
7 |
8 | * list item 1
9 | * list item 2
10 | * list item 3
11 | """
12 | type Dog {
13 | legs: Int
14 | }
15 |
16 | """
17 | abcde
18 | """
19 | type Seal {
20 | fins: Int
21 | }
22 |
23 | union Mammal = Dog | Seal
24 |
--------------------------------------------------------------------------------
/test/fixtures/union-test-2.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | Table of Contents
5 |
6 | * [Query](#query)
7 | * [Objects](#objects)
8 | * [Dog](#dog)
9 | * [Seal](#seal)
10 | * [Scalars](#scalars)
11 | * [Boolean](#boolean)
12 | * [Int](#int)
13 | * [String](#string)
14 | * [Unions](#unions)
15 | * [Mammal](#mammal)
16 |
17 |
18 |
19 | ## Query
20 |
21 |
22 |
23 | Field |
24 | Argument |
25 | Type |
26 | Description |
27 |
28 |
29 |
30 |
31 | mammals |
32 | [Mammal] |
33 | |
34 |
35 |
36 |
37 |
38 | ## Objects
39 |
40 | ### Dog
41 |
42 | *italic*
43 |
44 | * list item 1
45 | * list item 2
46 | * list item 3
47 |
48 |
49 |
50 |
51 | Field |
52 | Argument |
53 | Type |
54 | Description |
55 |
56 |
57 |
58 |
59 | legs |
60 | Int |
61 | |
62 |
63 |
64 |
65 |
66 | ### Seal
67 |
68 | abcde
69 |
70 |
71 |
72 |
73 | Field |
74 | Argument |
75 | Type |
76 | Description |
77 |
78 |
79 |
80 |
81 | fins |
82 | Int |
83 | |
84 |
85 |
86 |
87 |
88 | ## Scalars
89 |
90 | ### Boolean
91 |
92 | The `Boolean` scalar type represents `true` or `false`.
93 |
94 | ### Int
95 |
96 | The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
97 |
98 | ### String
99 |
100 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
101 |
102 |
103 | ## Unions
104 |
105 | ### Mammal
106 |
107 |
108 |
109 |
110 | Type |
111 | Description |
112 |
113 |
114 |
115 |
116 | Dog |
117 |
118 |
119 | *italic*
120 |
121 | * list item 1
122 | * list item 2
123 | * list item 3
124 |
125 | |
126 |
127 |
128 | Seal |
129 |
130 |
131 | abcde
132 |
133 | |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/test/fixtures/union-test.graphql:
--------------------------------------------------------------------------------
1 | "A human being"
2 | type Person {
3 | id: ID!
4 | firstName: String!
5 | lastName: String!
6 | email: String
7 | age: Int
8 | dob: String
9 | }
10 |
11 | """
12 | A group of **persons** working together for a purpose
13 |
14 | This is a more elaborate description
15 |
16 | * with some
17 | * items
18 | * to see
19 | * if this markdown is properly
20 | * translated
21 |
22 | """
23 | type Organization {
24 | "Node ID"
25 | id: ID!
26 | "Name of the organization"
27 | name: String!
28 | "Main contact email address"
29 | email: String
30 | "Date the organization was founded"
31 | founded: String
32 | "The CEO"
33 | ceo: Person
34 | }
35 |
36 | "Either a `Person` or an `Organization`"
37 | union Party = Person | Organization
38 |
39 | type Query {
40 | party(id: ID!): Party
41 | }
42 |
43 | extend type Query {
44 | "A field that was added with extend"
45 | extendo: String
46 | }
47 |
--------------------------------------------------------------------------------
/test/fixtures/union-test.md:
--------------------------------------------------------------------------------
1 | # Schema Types
2 |
3 |
4 | Table of Contents
5 |
6 | * [Query](#query)
7 | * [Objects](#objects)
8 | * [Organization](#organization)
9 | * [Person](#person)
10 | * [Scalars](#scalars)
11 | * [Boolean](#boolean)
12 | * [ID](#id)
13 | * [Int](#int)
14 | * [String](#string)
15 | * [Unions](#unions)
16 | * [Party](#party)
17 |
18 |
19 |
20 | ## Query
21 |
22 |
23 |
24 | Field |
25 | Argument |
26 | Type |
27 | Description |
28 |
29 |
30 |
31 |
32 | party |
33 | Party |
34 | |
35 |
36 |
37 | id |
38 | ID! |
39 | |
40 |
41 |
42 | extendo |
43 | String |
44 |
45 |
46 | A field that was added with extend
47 |
48 | |
49 |
50 |
51 |
52 |
53 | ## Objects
54 |
55 | ### Organization
56 |
57 | A group of **persons** working together for a purpose
58 |
59 | This is a more elaborate description
60 |
61 | * with some
62 | * items
63 | * to see
64 | * if this markdown is properly
65 | * translated
66 |
67 |
68 |
69 |
70 | Field |
71 | Argument |
72 | Type |
73 | Description |
74 |
75 |
76 |
77 |
78 | id |
79 | ID! |
80 |
81 |
82 | Node ID
83 |
84 | |
85 |
86 |
87 | name |
88 | String! |
89 |
90 |
91 | Name of the organization
92 |
93 | |
94 |
95 |
96 | email |
97 | String |
98 |
99 |
100 | Main contact email address
101 |
102 | |
103 |
104 |
105 | founded |
106 | String |
107 |
108 |
109 | Date the organization was founded
110 |
111 | |
112 |
113 |
114 | ceo |
115 | Person |
116 |
117 |
118 | The CEO
119 |
120 | |
121 |
122 |
123 |
124 |
125 | ### Person
126 |
127 | A human being
128 |
129 |
130 |
131 |
132 | Field |
133 | Argument |
134 | Type |
135 | Description |
136 |
137 |
138 |
139 |
140 | id |
141 | ID! |
142 | |
143 |
144 |
145 | firstName |
146 | String! |
147 | |
148 |
149 |
150 | lastName |
151 | String! |
152 | |
153 |
154 |
155 | email |
156 | String |
157 | |
158 |
159 |
160 | age |
161 | Int |
162 | |
163 |
164 |
165 | dob |
166 | String |
167 | |
168 |
169 |
170 |
171 |
172 | ## Scalars
173 |
174 | ### Boolean
175 |
176 | The `Boolean` scalar type represents `true` or `false`.
177 |
178 | ### ID
179 |
180 | The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
181 |
182 | ### Int
183 |
184 | The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
185 |
186 | ### String
187 |
188 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
189 |
190 |
191 | ## Unions
192 |
193 | ### Party
194 |
195 | Either a `Person` or an `Organization`
196 |
197 |
198 |
199 |
200 | Type |
201 | Description |
202 |
203 |
204 |
205 |
206 | Person |
207 |
208 |
209 | A human being
210 |
211 | |
212 |
213 |
214 | Organization |
215 |
216 |
217 | A group of **persons** working together for a purpose
218 |
219 | This is a more elaborate description
220 |
221 | * with some
222 | * items
223 | * to see
224 | * if this markdown is properly
225 | * translated
226 |
227 | |
228 |
229 |
230 |
231 |
--------------------------------------------------------------------------------
/test/index.test.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const tempy = require('tempy')
4 | const resolveFrom = require('resolve-from')
5 | const {
6 | run,
7 | loadSchemaJSON,
8 | renderSchema,
9 | updateSchema,
10 | } = require('../src/index')
11 |
12 | jest.mock('node-fetch')
13 | const fetch = require('node-fetch')
14 |
15 | function createPrinter() {
16 | const printer = (chunk) => {
17 | printer.output += `${chunk}\n`
18 | }
19 | printer.output = ''
20 | return printer
21 | }
22 |
23 | function createMockConsole() {
24 | return {
25 | log: createPrinter(),
26 | error: createPrinter(),
27 | }
28 | }
29 |
30 | function readFile(filename) {
31 | filename = path.resolve(__dirname, filename)
32 | return new Promise((resolve, reject) => {
33 | fs.readFile(filename, 'utf8', (err, data) => {
34 | err ? reject(err) : resolve(data)
35 | })
36 | })
37 | }
38 |
39 | describe('renderSchema()', () => {
40 | it('renders the GraphBrainz schema', async () => {
41 | const schema = await loadSchemaJSON('graphbrainz/schema.json')
42 | const printer = createPrinter()
43 | renderSchema(schema, { printer })
44 | const expected = await readFile('./fixtures/graphbrainz.md')
45 | expect(printer.output).toBe(expected)
46 | })
47 |
48 | it('supports Input Objects', async () => {
49 | const schema = await loadSchemaJSON(
50 | path.resolve(__dirname, './fixtures/input-objects.graphql')
51 | )
52 | const printer = createPrinter()
53 | renderSchema(schema, { printer })
54 | const expected = await readFile('./fixtures/input-objects.md')
55 | expect(printer.output).toBe(expected)
56 | })
57 |
58 | it('supports no rendering of table of contents', async () => {
59 | const schema = await loadSchemaJSON(
60 | path.resolve(__dirname, './fixtures/input-objects.graphql')
61 | )
62 | const printer = createPrinter()
63 | renderSchema(schema, { printer, skipTableOfContents: true })
64 | const expected = await readFile('./fixtures/no-toc.md')
65 | expect(printer.output).toBe(expected)
66 | })
67 |
68 | it('supports unions', async () => {
69 | const schema = await loadSchemaJSON(
70 | path.resolve(__dirname, './fixtures/union-test.graphql')
71 | )
72 | const printer = createPrinter()
73 | renderSchema(schema, { printer })
74 | const expected = await readFile('./fixtures/union-test.md')
75 | expect(printer.output).toBe(expected)
76 | })
77 |
78 | it('renders markdown properly in unions', async () => {
79 | const schema = await loadSchemaJSON(
80 | path.resolve(__dirname, './fixtures/union-test-2.graphql')
81 | )
82 | const printer = createPrinter()
83 | renderSchema(schema, { printer })
84 | const expected = await readFile('./fixtures/union-test-2.md')
85 | expect(printer.output).toBe(expected)
86 | })
87 |
88 | it('can link individual fields in the table of contents', async () => {
89 | const schema = await loadSchemaJSON(
90 | path.resolve(__dirname, './fixtures/input-objects.graphql')
91 | )
92 | const printer = createPrinter()
93 | renderSchema(schema, {
94 | printer,
95 | tocFieldTypes: ['Query', 'Mutation', 'MessageInput'],
96 | })
97 | const expected = await readFile('./fixtures/toc-fields.md')
98 | expect(printer.output).toBe(expected)
99 | })
100 | })
101 |
102 | describe('diffSchema()', () => {
103 | const schemaDiff = require('./fixtures/cover-art-archive')
104 |
105 | it('outputs a JSON schema containing only additions', async () => {
106 | expect(await schemaDiff).toMatchSnapshot()
107 | })
108 |
109 | it('can be rendered', async () => {
110 | const printer = createPrinter()
111 | renderSchema(await schemaDiff, { printer })
112 | const expected = await readFile('./fixtures/cover-art-archive.md')
113 | expect(printer.output).toBe(expected)
114 | })
115 | })
116 |
117 | describe('loadSchemaJSON()', () => {
118 | it('can load exported GraphQLSchema objects', async () => {
119 | const moduleSchema = await loadSchemaJSON('graphbrainz/lib/schema')
120 | expect(moduleSchema.__schema.queryType.name).toBe('Query')
121 | })
122 |
123 | it('can load JSON schema files', async () => {
124 | const jsonFileSchema = await loadSchemaJSON('graphbrainz/schema.json')
125 | expect(jsonFileSchema.__schema.queryType.name).toBe('Query')
126 | })
127 |
128 | it('can load GraphQL schema language files', async () => {
129 | const graphqlFileSchema = await loadSchemaJSON(
130 | path.resolve(__dirname, './fixtures/graphbrainz.graphql')
131 | )
132 | expect(graphqlFileSchema.__schema.queryType.name).toBe('Query')
133 | })
134 |
135 | it('can call fetch with correct parameters', async () => {
136 | fetch.mockImplementation(() =>
137 | Promise.resolve({
138 | json: () => resolveFrom('.', 'graphbrainz/schema.json'),
139 | })
140 | )
141 |
142 | await loadSchemaJSON('http://example.com', {
143 | headers: { key1: 'value1' },
144 | })
145 | expect(fetch.mock.calls[0][0]).toBe('http://example.com')
146 | expect(fetch.mock.calls[0][1].headers).toEqual({
147 | Accept: 'application/json',
148 | 'Content-Type': 'application/json',
149 | key1: 'value1',
150 | })
151 | })
152 | })
153 |
154 | describe('updateSchema()', () => {
155 | const filename = tempy.file()
156 |
157 | it('adds schema and comment markers to file if it does not exist', async () => {
158 | const initialSchema = await loadSchemaJSON('graphbrainz/schema.json')
159 |
160 | await updateSchema(filename, initialSchema)
161 | const actual = await readFile(filename)
162 | const expected = await readFile(
163 | './fixtures/graphbrainz-updateSchema-initial.md'
164 | )
165 | expect(actual).toBe(expected)
166 | })
167 |
168 | it('updates schema between comment markers in an existing file', async () => {
169 | const updatedSchema = await require('./fixtures/graphbrainz-updateSchema')
170 | await updateSchema(filename, updatedSchema)
171 | const actual = await readFile(filename)
172 | const expected = await readFile(
173 | './fixtures/graphbrainz-updateSchema-updated.md'
174 | )
175 | expect(actual).toBe(expected)
176 | })
177 | })
178 |
179 | describe('run()', () => {
180 | describe('with no args', () => {
181 | it('prints the help message', () => {
182 | const console = createMockConsole()
183 | run([], { console, exit: false })
184 | expect({
185 | stdout: console.log.output,
186 | stderr: console.error.output,
187 | }).toMatchSnapshot()
188 | })
189 | })
190 |
191 | describe('with --help arg', () => {
192 | it('prints the help message', () => {
193 | const console = createMockConsole()
194 | run(['--help'], { console, exit: false })
195 | expect({
196 | stdout: console.log.output,
197 | stderr: console.error.output,
198 | }).toMatchSnapshot()
199 | })
200 | })
201 | })
202 |
--------------------------------------------------------------------------------