@@ -87,7 +87,6 @@ ENV BUILD_SHA=$BUILD_SHA
|
||||
# Copy only what's needed to run the server
|
||||
COPY --chown=node:node package.json ./
|
||||
COPY --chown=node:node assets ./assets
|
||||
COPY --chown=node:node includes ./includes
|
||||
COPY --chown=node:node content ./content
|
||||
COPY --chown=node:node lib ./lib
|
||||
COPY --chown=node:node middleware ./middleware
|
||||
|
||||
58
components/graphql/BreakingChanges.tsx
Normal file
58
components/graphql/BreakingChanges.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import cx from 'classnames'
|
||||
import { LinkIcon } from '@primer/octicons-react'
|
||||
|
||||
import { BreakingChangesT } from 'components/graphql/types'
|
||||
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
|
||||
|
||||
type Props = {
|
||||
schema: BreakingChangesT
|
||||
}
|
||||
const slugger = new GithubSlugger()
|
||||
|
||||
export function BreakingChanges({ schema }: Props) {
|
||||
const changes = Object.keys(schema).map((date) => {
|
||||
const items = schema[date]
|
||||
const heading = `Changes scheduled for ${date}`
|
||||
const slug = slugger.slug(heading)
|
||||
|
||||
return (
|
||||
<div className={cx(styles.markdownBody, styles.automatedPages)} key={date}>
|
||||
<h2 id={slug}>
|
||||
<a className="doctocat-link" href={`#${slug}`}>
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
{heading}
|
||||
</h2>
|
||||
{items.map((item) => {
|
||||
const criticalityStyles =
|
||||
item.criticality === 'breaking'
|
||||
? 'color-border-danger color-bg-danger'
|
||||
: 'color-border-accent-emphasis color-bg-accent'
|
||||
const criticality = item.criticality === 'breaking' ? 'Breaking' : 'Dangerous'
|
||||
|
||||
return (
|
||||
<ul key={item.location}>
|
||||
<li>
|
||||
<span className={cx(criticalityStyles, 'border rounded-1 m-1 p-1')}>
|
||||
{criticality}
|
||||
</span>{' '}
|
||||
A change will be made to <code>{item.location}</code>.
|
||||
<p>
|
||||
<b>Description: </b>
|
||||
<span dangerouslySetInnerHTML={{ __html: item.description }} />
|
||||
</p>
|
||||
<p>
|
||||
<b>Reason: </b> <span dangerouslySetInnerHTML={{ __html: item.reason }} />
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
return <div>{changes}</div>
|
||||
}
|
||||
69
components/graphql/Changelog.tsx
Normal file
69
components/graphql/Changelog.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import React from 'react'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import cx from 'classnames'
|
||||
import { LinkIcon } from '@primer/octicons-react'
|
||||
|
||||
import { ChangelogItemT } from 'components/graphql/types'
|
||||
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
|
||||
|
||||
type Props = {
|
||||
changelogItems: ChangelogItemT[]
|
||||
}
|
||||
|
||||
export function Changelog({ changelogItems }: Props) {
|
||||
const changes = changelogItems.map((item) => {
|
||||
const heading = `Schema changes for ${item.date}`
|
||||
const slugger = new GithubSlugger()
|
||||
const slug = slugger.slug(heading)
|
||||
|
||||
return (
|
||||
<div className={cx(styles.markdownBody, styles.automatedPages)} key={item.date}>
|
||||
<h2 id={slug}>
|
||||
<a className="doctocat-link" href={`#${slug}`}>
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
{heading}
|
||||
</h2>
|
||||
{item.schemaChanges &&
|
||||
item.schemaChanges.map((change, index) => (
|
||||
<React.Fragment key={`${item.date}-schema-changes-${index}`}>
|
||||
<p>{change.title}</p>
|
||||
<ul>
|
||||
{change.changes.map((change) => (
|
||||
<li key={`${item.date}-${change}`}>
|
||||
<span dangerouslySetInnerHTML={{ __html: change }} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</React.Fragment>
|
||||
))}
|
||||
{item.previewChanges &&
|
||||
item.previewChanges.map((change, index) => (
|
||||
<React.Fragment key={`${item.date}-preview-changes-${index}`}>
|
||||
<p>{change.title}</p>
|
||||
<ul>
|
||||
{change.changes.map((change) => (
|
||||
<li key={`${item.date}-${change}`}>
|
||||
<span dangerouslySetInnerHTML={{ __html: change }} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</React.Fragment>
|
||||
))}
|
||||
{item.upcomingChanges &&
|
||||
item.upcomingChanges.map((change, index) => (
|
||||
<React.Fragment key={`${item.date}-upcoming-changes-${index}`}>
|
||||
<p>{change.title}</p>
|
||||
{change.changes.map((change) => (
|
||||
<li key={`${item.date}-${change}`}>
|
||||
<span dangerouslySetInnerHTML={{ __html: change }} />
|
||||
</li>
|
||||
))}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
return <div>{changes}</div>
|
||||
}
|
||||
31
components/graphql/Enum.tsx
Normal file
31
components/graphql/Enum.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react'
|
||||
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import type { EnumT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: EnumT
|
||||
}
|
||||
|
||||
export function Enum({ item }: Props) {
|
||||
const { t } = useTranslation('products')
|
||||
const heading = t('graphql.reference.values')
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item} heading={heading}>
|
||||
{item.values.map((value) => (
|
||||
<React.Fragment key={`${value.name}-${value.description}`}>
|
||||
<p>
|
||||
<strong>{value.name}</strong>
|
||||
</p>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: value.description,
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
48
components/graphql/GraphqlItem.tsx
Normal file
48
components/graphql/GraphqlItem.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { LinkIcon } from '@primer/octicons-react'
|
||||
|
||||
import type { GraphqlT } from './types'
|
||||
import { Notice } from './Notice'
|
||||
|
||||
type Props = {
|
||||
item: GraphqlT
|
||||
heading?: string
|
||||
headingLevel?: number
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export function GraphqlItem({ item, heading, children, headingLevel = 2 }: Props) {
|
||||
const lowerCaseName = item.name.toLowerCase()
|
||||
return (
|
||||
<>
|
||||
{headingLevel === 2 && (
|
||||
<h2 id={lowerCaseName}>
|
||||
<a className="doctocat-link" href={`#${lowerCaseName}`}>
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
{item.name}
|
||||
</h2>
|
||||
)}
|
||||
{headingLevel === 3 && (
|
||||
<h3 id={lowerCaseName}>
|
||||
<a className="doctocat-link" href={`#${lowerCaseName}`}>
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
{item.name}
|
||||
</h3>
|
||||
)}
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.description,
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
{item.preview && <Notice item={item} variant="preview" />}
|
||||
{item.isDeprecated && <Notice item={item} variant="deprecation" />}
|
||||
</div>
|
||||
<div>
|
||||
{heading && <h4>{heading}</h4>}
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
108
components/graphql/GraphqlPage.tsx
Normal file
108
components/graphql/GraphqlPage.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import React from 'react'
|
||||
import cx from 'classnames'
|
||||
import { LinkIcon } from '@primer/octicons-react'
|
||||
|
||||
import { Enum } from 'components/graphql/Enum'
|
||||
import { InputObject } from 'components/graphql/InputObject'
|
||||
import { Interface } from 'components/graphql/Interface'
|
||||
import { Scalar } from 'components/graphql/Scalar'
|
||||
import { Mutation } from 'components/graphql/Mutation'
|
||||
import { Object } from 'components/graphql/Object'
|
||||
import { Query } from 'components/graphql/Query'
|
||||
import { Union } from 'components/graphql/Union'
|
||||
import type {
|
||||
EnumT,
|
||||
InputObjectT,
|
||||
InterfaceT,
|
||||
MutationT,
|
||||
ObjectT,
|
||||
QueryT,
|
||||
ScalarT,
|
||||
UnionT,
|
||||
} from 'components/graphql/types'
|
||||
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
|
||||
|
||||
type Props = {
|
||||
schema: Object
|
||||
pageName: string
|
||||
objects?: ObjectT[]
|
||||
}
|
||||
|
||||
export const GraphqlPage = ({ schema, pageName, objects }: Props) => {
|
||||
const graphqlItems: JSX.Element[] = [] // In the case of the H2s for Queries
|
||||
|
||||
// The queries page has two heading sections (connections and fields)
|
||||
// So we need to add the heading component and the children under it
|
||||
// for each section.
|
||||
if (pageName === 'queries') {
|
||||
graphqlItems.push(
|
||||
<h2 id="connections" key="query-connections-heading">
|
||||
<a className="doctocat-link" href="#connections">
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
Connections
|
||||
</h2>
|
||||
)
|
||||
graphqlItems.push(
|
||||
...(schema as QueryT).connections.map((item) => (
|
||||
<Query item={item} key={item.id + item.name} />
|
||||
))
|
||||
)
|
||||
graphqlItems.push(
|
||||
<h2 id="fields" key="query-fields-heading">
|
||||
<a className="doctocat-link" href="#fields">
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
Fields
|
||||
</h2>
|
||||
)
|
||||
|
||||
graphqlItems.push(
|
||||
...(schema as QueryT).fields.map((item) => <Query item={item} key={item.id + item.name} />)
|
||||
)
|
||||
} else if (pageName === 'enums') {
|
||||
graphqlItems.push(
|
||||
...(schema as EnumT[]).map((item) => {
|
||||
return <Enum key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'inputObjects') {
|
||||
graphqlItems.push(
|
||||
...(schema as InputObjectT[]).map((item) => {
|
||||
return <InputObject key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'interfaces' && objects) {
|
||||
graphqlItems.push(
|
||||
...(schema as InterfaceT[]).map((item) => {
|
||||
return <Interface key={item.id} item={item} objects={objects} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'mutations') {
|
||||
graphqlItems.push(
|
||||
...(schema as MutationT[]).map((item) => {
|
||||
return <Mutation key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'objects') {
|
||||
graphqlItems.push(
|
||||
...(schema as ObjectT[]).map((item) => {
|
||||
return <Object key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'scalars') {
|
||||
graphqlItems.push(
|
||||
...(schema as ScalarT[]).map((item) => {
|
||||
return <Scalar key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
} else if (pageName === 'unions') {
|
||||
graphqlItems.push(
|
||||
...(schema as UnionT[]).map((item) => {
|
||||
return <Union key={item.id} item={item} />
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return <div className={cx(styles.automatedPages, styles.markdownBody)}>{graphqlItems}</div>
|
||||
}
|
||||
18
components/graphql/InputObject.tsx
Normal file
18
components/graphql/InputObject.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { Table } from './Table'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { InputObjectT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: InputObjectT
|
||||
}
|
||||
|
||||
export function InputObject({ item }: Props) {
|
||||
const { t } = useTranslation('products')
|
||||
const heading = t('graphql.reference.input_fields')
|
||||
return (
|
||||
<GraphqlItem item={item} heading={heading}>
|
||||
<Table fields={item.inputFields} />
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
47
components/graphql/Interface.tsx
Normal file
47
components/graphql/Interface.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { Table } from './Table'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { ObjectT, InterfaceT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: InterfaceT
|
||||
objects: ObjectT[]
|
||||
}
|
||||
|
||||
export function Interface({ item, objects }: Props) {
|
||||
const { locale } = useRouter()
|
||||
const { t } = useTranslation('products')
|
||||
const heading = t('graphql.reference.implemented_by')
|
||||
const heading2 = t('graphql.reference.fields')
|
||||
|
||||
const implementedBy = objects.filter(
|
||||
(object) =>
|
||||
object.implements &&
|
||||
object.implements.some((implementsItem) => implementsItem.name === item.name)
|
||||
)
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item} heading={heading}>
|
||||
<ul>
|
||||
{implementedBy.map((object) => (
|
||||
<li key={`${item.id}-${item.name}-${object.href}-${object.name}`}>
|
||||
<code>
|
||||
<Link href={object.href} locale={locale}>
|
||||
{object.name}
|
||||
</Link>
|
||||
</code>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{item.fields && (
|
||||
<>
|
||||
<h4>{heading2}</h4>
|
||||
<Table fields={item.fields} />
|
||||
</>
|
||||
)}
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
45
components/graphql/Mutation.tsx
Normal file
45
components/graphql/Mutation.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { Notice } from './Notice'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { Table } from './Table'
|
||||
import type { MutationT } from './types'
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
item: MutationT
|
||||
}
|
||||
|
||||
export function Mutation({ item }: Props) {
|
||||
const { locale } = useRouter()
|
||||
const { t } = useTranslation('products')
|
||||
const heading = t('graphql.reference.input_fields')
|
||||
const heading2 = t('graphql.reference.return_fields')
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item} heading={heading}>
|
||||
{item.inputFields.map((input) => (
|
||||
<React.Fragment key={input.id}>
|
||||
<ul>
|
||||
<li>
|
||||
<code>{input.name}</code> (
|
||||
<code>
|
||||
<Link href={input.href} locale={locale}>
|
||||
{input.type}
|
||||
</Link>
|
||||
</code>
|
||||
)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{input.preview && <Notice item={input} variant="preview" />}
|
||||
{input.isDeprecated && <Notice item={input} variant="deprecation" />}
|
||||
<h4>{heading2}</h4>
|
||||
<Table fields={item.returnFields} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
51
components/graphql/Notice.tsx
Normal file
51
components/graphql/Notice.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { GraphqlT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: GraphqlT
|
||||
variant: 'preview' | 'deprecation'
|
||||
}
|
||||
|
||||
export function Notice({ item, variant = 'preview' }: Props) {
|
||||
const { locale } = useRouter()
|
||||
|
||||
const { t } = useTranslation('products')
|
||||
const previewTitle =
|
||||
variant === 'preview'
|
||||
? t('rest.reference.preview_notice')
|
||||
: t('graphql.reference.deprecation_notice')
|
||||
const noticeStyle =
|
||||
variant === 'preview'
|
||||
? 'note color-border-accent-emphasis color-bg-accent'
|
||||
: 'warning color-border-danger color-bg-danger'
|
||||
return (
|
||||
<div className={`${noticeStyle} extended-markdown border rounded-1 my-3 p-3 f5`}>
|
||||
<p>
|
||||
<b>{previewTitle}</b>
|
||||
</p>
|
||||
{variant === 'preview' && item.preview ? (
|
||||
<p>
|
||||
<code>{item.name}</code> is available under the{' '}
|
||||
<Link href={item.preview.href} locale={locale}>
|
||||
{item.preview.title}
|
||||
</Link>
|
||||
. {t('graphql.reference.preview_period')}
|
||||
</p>
|
||||
) : item.deprecationReason ? (
|
||||
<div>
|
||||
<p>
|
||||
<code>{item.name}</code> is deprecated.
|
||||
</p>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.deprecationReason,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
46
components/graphql/Object.tsx
Normal file
46
components/graphql/Object.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { Table } from './Table'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { ObjectT, ImplementsT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: ObjectT
|
||||
}
|
||||
|
||||
export function Object({ item }: Props) {
|
||||
const { locale } = useRouter()
|
||||
const { t } = useTranslation('products')
|
||||
const heading1 = t('graphql.reference.implements')
|
||||
const heading2 = t('graphql.reference.fields')
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item}>
|
||||
{item.implements && (
|
||||
<>
|
||||
<h3>{heading1}</h3>
|
||||
<ul>
|
||||
{item.implements.map((implement: ImplementsT) => (
|
||||
<li key={`${implement.id}-${implement.href}-${implement.name}`}>
|
||||
<code>
|
||||
<Link href={implement.href} locale={locale}>
|
||||
{implement.name}
|
||||
</Link>
|
||||
</code>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
|
||||
{item.fields && (
|
||||
<>
|
||||
<h3>{heading2}</h3>
|
||||
<Table fields={item.fields} />
|
||||
</>
|
||||
)}
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
58
components/graphql/Previews.tsx
Normal file
58
components/graphql/Previews.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import cx from 'classnames'
|
||||
import { LinkIcon } from '@primer/octicons-react'
|
||||
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { PreviewT } from 'components/graphql/types'
|
||||
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
|
||||
|
||||
type Props = {
|
||||
schema: PreviewT[]
|
||||
}
|
||||
|
||||
export function Previews({ schema }: Props) {
|
||||
const previews = schema.map((item) => {
|
||||
const slugger = new GithubSlugger()
|
||||
const slug = slugger.slug(item.title)
|
||||
const { t } = useTranslation('products')
|
||||
|
||||
return (
|
||||
<div className={cx(styles.markdownBody, styles.automatedPages)} key={slug}>
|
||||
<h2 id={slug}>
|
||||
<a className="doctocat-link" href={`#${slug}`}>
|
||||
<LinkIcon className="octicon-link" size="small" />
|
||||
</a>
|
||||
{item.title}
|
||||
</h2>
|
||||
<p>{item.description}</p>
|
||||
<p>{t('graphql.overview.preview_header')}</p>
|
||||
<pre>
|
||||
<code>{item.accept_header}</code>
|
||||
</pre>
|
||||
<p>{t('graphql.overview.preview_schema_members')}:</p>
|
||||
<ul>
|
||||
{item.toggled_on.map((change) => (
|
||||
<li key={change + slug}>
|
||||
<code>{change}</code>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{item.announcement && (
|
||||
<p>
|
||||
<b>{t('graphql.overview.announced')}: </b>
|
||||
<a href={item.announcement.url}>{item.announcement.date}</a>
|
||||
</p>
|
||||
)}
|
||||
{item.updates && (
|
||||
<p>
|
||||
<b>{t('graphql.overview.updates')}: </b>
|
||||
<a href={item.updates.url}>{item.updates.date}</a>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
return <div>{previews}</div>
|
||||
}
|
||||
38
components/graphql/Query.tsx
Normal file
38
components/graphql/Query.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { Table } from './Table'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { QueryItemT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: QueryItemT
|
||||
}
|
||||
|
||||
export function Query({ item }: Props) {
|
||||
const { locale } = useRouter()
|
||||
const { t } = useTranslation('products')
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item} headingLevel={3}>
|
||||
<div>
|
||||
<p>
|
||||
<b>{t('graphql.reference.type')}: </b>
|
||||
<Link href={item.href} locale={locale}>
|
||||
{item.type}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{item.args.length > 0 && (
|
||||
<>
|
||||
<h4>{t('graphql.reference.arguments')}</h4>
|
||||
<Table fields={item.args} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
10
components/graphql/Scalar.tsx
Normal file
10
components/graphql/Scalar.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { ScalarT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: ScalarT
|
||||
}
|
||||
|
||||
export function Scalar({ item }: Props) {
|
||||
return <GraphqlItem item={item} />
|
||||
}
|
||||
100
components/graphql/Table.tsx
Normal file
100
components/graphql/Table.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { Notice } from './Notice'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { FieldT } from './types'
|
||||
|
||||
type Props = {
|
||||
fields: FieldT[]
|
||||
}
|
||||
|
||||
export function Table({ fields }: Props) {
|
||||
const { locale } = useRouter()
|
||||
|
||||
const { t } = useTranslation('products')
|
||||
const tableName = t('graphql.reference.name')
|
||||
const tableDescription = t('graphql.reference.description')
|
||||
|
||||
return (
|
||||
<table className="fields width-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{tableName}</th>
|
||||
<th>{tableDescription}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{fields.map((field) => (
|
||||
<tr key={field.name}>
|
||||
<td>
|
||||
<p>
|
||||
<code>{field.name}</code> (
|
||||
<code>
|
||||
<Link href={field.href} locale={locale}>
|
||||
{field.type}
|
||||
</Link>
|
||||
</code>
|
||||
)
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
{field.description ? (
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: field.description,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
'N/A'
|
||||
)}
|
||||
{field.defaultValue !== undefined && (
|
||||
<p>
|
||||
The default value is <code>{field.defaultValue.toString()}</code>.
|
||||
</p>
|
||||
)}
|
||||
{field.preview && <Notice item={field} variant="preview" />}
|
||||
{field.isDeprecated && <Notice item={field} variant="deprecation" />}
|
||||
|
||||
{field.arguments && (
|
||||
<div className="border rounded-1 mt-3 mb-3 p-3 color-bg-subtle f5">
|
||||
<h4 className="pt-0 mt-0">{t('graphql.reference.arguments')}</h4>
|
||||
{field.arguments.map((argument, index) => (
|
||||
<ul
|
||||
key={`${index}-${argument.type.name}-${argument.type.href}`}
|
||||
className="list-style-none pl-0"
|
||||
>
|
||||
<li className="border-top mt-2">
|
||||
<p className="mt-2">
|
||||
<code>{argument.name}</code> (
|
||||
<code>
|
||||
<Link href={argument.type.href} locale={locale}>
|
||||
{argument.type.name}
|
||||
</Link>
|
||||
</code>
|
||||
)
|
||||
</p>
|
||||
{
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: argument.description,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{argument.defaultValue !== undefined && (
|
||||
<p>
|
||||
The default value is <code>{argument.defaultValue.toString()}</code>.
|
||||
</p>
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
30
components/graphql/Union.tsx
Normal file
30
components/graphql/Union.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { GraphqlItem } from './GraphqlItem'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import type { UnionT } from './types'
|
||||
|
||||
type Props = {
|
||||
item: UnionT
|
||||
}
|
||||
|
||||
export function Union({ item }: Props) {
|
||||
const { locale } = useRouter()
|
||||
const { t } = useTranslation('products')
|
||||
const heading = t('graphql.reference.possible_types')
|
||||
|
||||
return (
|
||||
<GraphqlItem item={item} heading={heading}>
|
||||
<ul>
|
||||
{item.possibleTypes.map((type) => (
|
||||
<li key={type.id}>
|
||||
<Link href={type.href} locale={locale}>
|
||||
{type.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</GraphqlItem>
|
||||
)
|
||||
}
|
||||
137
components/graphql/types.tsx
Normal file
137
components/graphql/types.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
export type PreviewT = {
|
||||
title: string
|
||||
description: string
|
||||
toggled_by: string
|
||||
toggled_on: []
|
||||
owning_teams: []
|
||||
accept_header: string
|
||||
href: string
|
||||
announcement: {
|
||||
date: string
|
||||
url: string
|
||||
}
|
||||
updates: {
|
||||
date: string
|
||||
url: string
|
||||
}
|
||||
}
|
||||
|
||||
export type UpcomingChangesT = {
|
||||
location: string
|
||||
description: string
|
||||
reason: string
|
||||
date: string
|
||||
criticality: 'breaking' | 'dangerous'
|
||||
owner: string
|
||||
}
|
||||
|
||||
export type GraphqlT = {
|
||||
name: string
|
||||
kind: string
|
||||
id: string
|
||||
href: string
|
||||
description: string
|
||||
type?: string
|
||||
size?: number
|
||||
isDeprecated?: boolean
|
||||
deprecationReason?: string
|
||||
preview?: PreviewT
|
||||
defaultValue?: boolean
|
||||
}
|
||||
|
||||
export type ImplementsT = {
|
||||
name: string
|
||||
id: string
|
||||
href: string
|
||||
}
|
||||
|
||||
export type ArgumentT = {
|
||||
name: string
|
||||
description: string
|
||||
defaultValue?: string | boolean
|
||||
type: {
|
||||
name: string
|
||||
id: string
|
||||
kind: string
|
||||
href: string
|
||||
}
|
||||
}
|
||||
|
||||
export type FieldT = GraphqlT & {
|
||||
arguments?: ArgumentT[]
|
||||
}
|
||||
|
||||
export type QueryItemT = GraphqlT & {
|
||||
args: GraphqlT[]
|
||||
}
|
||||
|
||||
export type QueryT = { connections: QueryItemT[]; fields: QueryItemT[] }
|
||||
|
||||
export type MutationT = GraphqlT & {
|
||||
inputFields: FieldT[]
|
||||
returnFields: FieldT[]
|
||||
}
|
||||
|
||||
export type ObjectT = GraphqlT & {
|
||||
fields: FieldT[]
|
||||
implements?: ImplementsT[]
|
||||
}
|
||||
|
||||
export type InterfaceT = GraphqlT & {
|
||||
fields: FieldT[]
|
||||
}
|
||||
|
||||
export type EnumValuesT = {
|
||||
name: string
|
||||
description: string
|
||||
}
|
||||
|
||||
export type EnumT = GraphqlT & {
|
||||
values: EnumValuesT[]
|
||||
}
|
||||
|
||||
export type UnionT = GraphqlT & {
|
||||
possibleTypes: ImplementsT[]
|
||||
}
|
||||
|
||||
export type InputFieldsT = GraphqlT & {
|
||||
type: string
|
||||
}
|
||||
|
||||
export type InputObjectT = GraphqlT & {
|
||||
inputFields: FieldT[]
|
||||
}
|
||||
|
||||
export type ScalarT = GraphqlT & {
|
||||
kind?: string
|
||||
}
|
||||
|
||||
export type AllVersionsT = {
|
||||
[versions: string]: {
|
||||
miscVersionName: string
|
||||
}
|
||||
}
|
||||
|
||||
type ChangeT = {
|
||||
title: string
|
||||
changes: string[]
|
||||
}
|
||||
|
||||
export type ChangelogItemT = {
|
||||
date: string
|
||||
schemaChanges: ChangeT[]
|
||||
previewChanges: ChangeT[]
|
||||
upcomingChanges: ChangeT[]
|
||||
}
|
||||
|
||||
export type BreakingChangeT = {
|
||||
location: string
|
||||
description: string
|
||||
reason: string
|
||||
date: string
|
||||
criticality: string
|
||||
}
|
||||
|
||||
export type BreakingChangesT = {
|
||||
[date: string]: BreakingChangeT[]
|
||||
}
|
||||
@@ -72,3 +72,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.automatedPages {
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--color-fg-default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
title: Breaking changes
|
||||
intro: 'Learn about recent and upcoming breaking changes to the {% data variables.product.prodname_dotcom %} GraphQL API.'
|
||||
intro: "Learn about recent and upcoming breaking changes to the {% data variables.product.prodname_dotcom %} GraphQL API."
|
||||
redirect_from:
|
||||
- /v4/breaking_changes
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -16,25 +16,9 @@ topics:
|
||||
|
||||
Breaking changes are any changes that might require action from our integrators. We divide these changes into two categories:
|
||||
|
||||
- **Breaking:** Changes that will break existing queries to the GraphQL API. For example, removing a field would be a breaking change.
|
||||
- **Dangerous:** Changes that won't break existing queries but could affect the runtime behavior of clients. Adding an enum value is an example of a dangerous change.
|
||||
- **Breaking:** Changes that will break existing queries to the GraphQL API. For example, removing a field would be a breaking change.
|
||||
- **Dangerous:** Changes that won't break existing queries but could affect the runtime behavior of clients. Adding an enum value is an example of a dangerous change.
|
||||
|
||||
We strive to provide stable APIs for our integrators. When a new feature is still evolving, we release it behind a [schema preview](/graphql/overview/schema-previews).
|
||||
|
||||
We'll announce upcoming breaking changes at least three months before making changes to the GraphQL schema, to give integrators time to make the necessary adjustments. Changes go into effect on the first day of a quarter (January 1st, April 1st, July 1st, or October 1st). For example, if we announce a change on January 15th, it will be made on July 1st.
|
||||
|
||||
{% for date in graphql.upcomingChangesForCurrentVersion %}
|
||||
## Changes scheduled for {{ date[0] }}
|
||||
|
||||
{% for change in date[1] %}
|
||||
<ul>
|
||||
<li><span class="border rounded-1 m-1 p-1 {% if change.criticality == 'breaking' %}color-border-danger color-bg-danger{% else %}color-border-accent-emphasis color-bg-accent{% endif %}">{% if change.criticality == 'breaking' %}Breaking{% else %}Dangerous{% endif %}</span> A change will be made to <code>{{ change.location }}</code>.
|
||||
|
||||
<p><b>Description:</b> {{ change.description }}</p>
|
||||
|
||||
<p><b>Reason:</b> {{ change.reason }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,44 +1,15 @@
|
||||
---
|
||||
title: Changelog
|
||||
intro: 'The GraphQL schema changelog is a list of recent and upcoming changes to our GraphQL API schema. It includes backwards-compatible changes, schema previews, and upcoming breaking changes.'
|
||||
intro: "The GraphQL schema changelog is a list of recent and upcoming changes to our GraphQL API schema. It includes backwards-compatible changes, schema previews, and upcoming breaking changes."
|
||||
redirect_from:
|
||||
- /v4/changelog
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
|
||||
Breaking changes include changes that will break existing queries or could affect the runtime behavior of clients. For a list of breaking changes and when they will occur, see our [breaking changes log](/graphql/overview/breaking-changes).
|
||||
|
||||
{% for entry in graphql.changelog %}
|
||||
## Schema Changes for {{ entry.date }}
|
||||
|
||||
{% for schemaChange in entry.schemaChanges %}
|
||||
{{ schemaChange.title }}
|
||||
|
||||
{% for change in schemaChange.changes %}
|
||||
* {{ change }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for previewChange in entry.previewChanges %}
|
||||
{{ previewChange.title }}
|
||||
|
||||
{% for change in previewChange.changes %}
|
||||
* {{ change }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for upcomingChange in entry.upcomingChanges %}
|
||||
{{ upcomingChange.title }}
|
||||
|
||||
{% for change in upcomingChange.changes %}
|
||||
* {{ change }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
title: Schema previews
|
||||
intro: 'You can preview upcoming features and changes to the {% data variables.product.prodname_dotcom %} GraphQL schema before they are added to the {% data variables.product.prodname_dotcom %} GraphQL API.'
|
||||
intro: "You can preview upcoming features and changes to the {% data variables.product.prodname_dotcom %} GraphQL schema before they are added to the {% data variables.product.prodname_dotcom %} GraphQL API."
|
||||
redirect_from:
|
||||
- /v4/previews
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -23,32 +23,3 @@ To access a schema preview, you'll need to provide a custom [media type](/rest/o
|
||||
**Note:** The GraphQL schema members under preview cannot be accessed via the Explorer at this time.
|
||||
|
||||
{% endnote %}
|
||||
|
||||
{% for preview in graphql.previewsForCurrentVersion %}
|
||||
## {{ preview.title }}
|
||||
|
||||
{{ preview.description }}
|
||||
|
||||
To toggle this preview and access the following schema members, you must provide a custom media type in the `Accept` header:
|
||||
|
||||
```
|
||||
{{ preview.accept_header }}
|
||||
```
|
||||
|
||||
Previewed schema members:
|
||||
|
||||
{% for schemaMemberPath in preview.toggled_on %}
|
||||
- `{{ schemaMemberPath }}`
|
||||
{% endfor %}
|
||||
|
||||
{% if preview.announcement %}
|
||||
**Announced:** [{{ preview.announcement.date }}]({{ preview.announcement.url }})
|
||||
{% endif %}
|
||||
|
||||
{% if preview.updates %}
|
||||
{% for update in preview.updates %}
|
||||
**Updated:** [{{ update.date }}]({{ update.url }})
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/enum
|
||||
- /v4/reference/enum
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -20,6 +20,4 @@ For example, the [`Issue`](/graphql/reference/objects#issue) object has a field
|
||||
|
||||
For more information, see "[Introduction to GraphQL](/graphql/guides/introduction-to-graphql)."
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.enums %}
|
||||
{% include graphql-enum %}
|
||||
{% endfor %}
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/input_object
|
||||
- /v4/reference/input_object
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -20,5 +20,4 @@ For example, [`CommitAuthor`](/graphql/reference/input-objects#commitauthor) tak
|
||||
|
||||
For more information, see "[About mutations](/graphql/guides/forming-calls-with-graphql#about-mutations)."
|
||||
|
||||
<!-- this page is pre-rendered by scripts because it's too big to load dynamically -->
|
||||
<!-- see lib/graphql/static/prerendered-input-objects.json -->
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/interface
|
||||
- /v4/reference/interface
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -20,6 +20,4 @@ For example, [`Lockable`](/graphql/reference/interfaces#lockable) is an interfac
|
||||
|
||||
For more information, see "[Implementation](/graphql/guides/introduction-to-graphql#implementation)."
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.interfaces %}
|
||||
{% include graphql-interface %}
|
||||
{% endfor %}
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/mutation
|
||||
- /v4/reference/mutation
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -18,5 +18,4 @@ Every GraphQL schema has a root type for both queries and mutations. The [mutati
|
||||
|
||||
For more information, see "[About mutations](/graphql/guides/forming-calls-with-graphql#about-mutations)."
|
||||
|
||||
<!-- this page is pre-rendered by scripts because it's too big to load dynamically -->
|
||||
<!-- see lib/graphql/static/prerendered-mutations.json -->
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/object
|
||||
- /v4/reference/object
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -20,5 +20,4 @@ For example, the [`Repository`](/graphql/reference/objects#repository) object ha
|
||||
|
||||
For more information, see "[Introduction to GraphQL](/graphql/guides/introduction-to-graphql)."
|
||||
|
||||
<!-- this page is pre-rendered by scripts because it's too big to load dynamically -->
|
||||
<!-- see lib/graphql/static/prerendered-objects.json -->
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: Queries
|
||||
miniTocMaxHeadingLevel: 2
|
||||
miniTocMaxHeadingLevel: 3
|
||||
redirect_from:
|
||||
- /v4/query
|
||||
- /v4/reference/query
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -25,14 +25,4 @@ For more information, see "[About queries](/graphql/guides/forming-calls-with-gr
|
||||
|
||||
{% endnote %}
|
||||
|
||||
## Connections
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.queries.connections %}
|
||||
{% include graphql-query %}
|
||||
{% endfor %}
|
||||
|
||||
## Fields
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.queries.fields %}
|
||||
{% include graphql-query %}
|
||||
{% endfor %}
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/scalar
|
||||
- /v4/reference/scalar
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -18,8 +18,6 @@ topics:
|
||||
|
||||
When calling the GraphQL API, you must specify nested subfields until you return only scalars.
|
||||
|
||||
For more information, see "[Introduction to GraphQL](/graphql/guides/introduction-to-graphql#field)."
|
||||
For more information, see "[Introduction to GraphQL](/graphql/guides/introduction-to-graphql#field)."
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.scalars %}
|
||||
{% include graphql-scalar %}
|
||||
{% endfor %}
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -4,10 +4,10 @@ redirect_from:
|
||||
- /v4/union
|
||||
- /v4/reference/union
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
fpt: "*"
|
||||
ghec: "*"
|
||||
ghes: "*"
|
||||
ghae: "*"
|
||||
topics:
|
||||
- API
|
||||
---
|
||||
@@ -20,6 +20,4 @@ For example, a field marked as an [`ProjectCardItem`](/graphql/reference/unions#
|
||||
|
||||
For more information, see "[Introduction to GraphQL](/graphql/guides/introduction-to-graphql)."
|
||||
|
||||
{% for item in graphql.schemaForCurrentVersion.unions %}
|
||||
{% include graphql-union %}
|
||||
{% endfor %}
|
||||
<!-- Content after this section is automatically generated -->
|
||||
|
||||
@@ -106,6 +106,12 @@ products:
|
||||
possible_types: Possible types
|
||||
preview_notice: Preview notice
|
||||
deprecation_notice: Deprecation notice
|
||||
preview_period: During the preview period, the API may change without notice.
|
||||
overview:
|
||||
preview_header: 'To toggle this preview and access the following schema members, you must provide a custom media type in the `Accept` header:'
|
||||
preview_schema_members: 'Previewed schema members'
|
||||
announced: Announced
|
||||
updates: Updates
|
||||
rest:
|
||||
reference:
|
||||
default: Default
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Includes
|
||||
|
||||
The files in this directory are "includes", snippets of HTML that can be
|
||||
reused in multiple layouts or pages. In Ruby on Rails parlance, these are
|
||||
called "partials".
|
||||
|
||||
## Using Includes
|
||||
|
||||
This example injects the contents of `includes/graphql-enum.html` into the
|
||||
page:
|
||||
|
||||
```
|
||||
{% include graphql-enum %}
|
||||
```
|
||||
|
||||
## Writing Includes
|
||||
|
||||
Includes must have a `.html` extension.
|
||||
@@ -1,15 +0,0 @@
|
||||
<svg
|
||||
aria-hidden
|
||||
role="img"
|
||||
class="octicon-link"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
style="display: inline-block; user-select: none; vertical-align: middle"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 606 B |
@@ -1,14 +0,0 @@
|
||||
{% if field.arguments %}
|
||||
<div class="border rounded-1 mt-3 mb-3 p-3 color-bg-subtle f5">
|
||||
<h4 class="pt-0 mt-0">{% data ui.products.graphql.reference.arguments %}</h4>
|
||||
{% for arg in arguments %}
|
||||
<ul class="list-style-none pl-0">
|
||||
<li class="border-top mt-2">
|
||||
<p class="mt-2"><code>{{ arg.name }}</code> (<code><a href="/{{ currentLanguage }}{{ arg.type.href }}">{{ arg.type.name }}</a></code>)</p>
|
||||
{{ arg.description }}
|
||||
{% if arg.defaultValue or arg.defaultValue == false %}<p>The default value is <code>{{ arg.defaultValue }}</code>.</p>{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,6 +0,0 @@
|
||||
{% if item.isDeprecated %}
|
||||
<div class="extended-markdown warning border rounded-1 mt-3 mb-4 p-3 color-border-danger color-bg-danger f5">
|
||||
<p><b>{% data ui.products.graphql.reference.deprecation_notice %}</b></p>
|
||||
<p><code>{{ item.name }}</code> is deprecated.</p>{{ item.deprecationReason }}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,20 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
|
||||
<h4>{% data ui.products.graphql.reference.values %}</h4>
|
||||
{% for value in item.values %}
|
||||
<p><strong>{{ value.name }}</strong></p>
|
||||
{{ value.description }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,25 +0,0 @@
|
||||
<table class="fields width-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% data ui.products.graphql.reference.name %}</th>
|
||||
<th>{% data ui.products.graphql.reference.description %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for field in fields %}
|
||||
<tr>
|
||||
<td><p><code>{{ field.name }}</code> (<code><a href="/{{ currentLanguage }}{{ field.href }}">{{ field.type }}</a></code>)</p></td>
|
||||
<td>{% if field.description %}{{ field.description }}{% else %}N/A{% endif %}
|
||||
{% if field.defaultValue or field.defaultValue == false %}<p>The default value is <code>{{ field.defaultValue }}</code>.</p>{% endif %}
|
||||
|
||||
{% assign item = field %}
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
|
||||
{% assign arguments = field.arguments %}
|
||||
{% include graphql-arguments %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,9 +0,0 @@
|
||||
<h4>{% data ui.products.graphql.reference.input_fields %}</h4>
|
||||
{% for inputField in inputFields %}
|
||||
<ul>
|
||||
<li><code>{{ inputField.name }}</code> (<code><a href="/{{ currentLanguage }}{{ inputField.href }}">{{ inputField.type }}</a></code>)</li>
|
||||
</ul>
|
||||
{% assign item = inputField %}
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
{% endfor %}
|
||||
@@ -1,16 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %} {% include graphql-deprecation %}
|
||||
|
||||
<h4>{% data ui.products.graphql.reference.input_fields %}</h4>
|
||||
{% assign fields = item.inputFields %} {% include graphql-fields %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,34 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
|
||||
<!-- Calculate and render "Implemented By" section -->
|
||||
<!-- TODO instead of calculating in layout, better to calculate in graphql-data? -->
|
||||
<h4>{% data ui.products.graphql.reference.implemented_by %}</h4>
|
||||
<ul>
|
||||
<!-- Loop over objects, then loop over object interfaces, and find a match -->
|
||||
{% for object in graphql.schemaForCurrentVersion.objects %}
|
||||
{% for interface in object.implements %}
|
||||
{% if interface.name == item.name %}
|
||||
<li>
|
||||
<code><a href="/{{ currentLanguage }}{{ object.href }}">{{ object.name }}</a></code>
|
||||
</li>
|
||||
{% endif %} {% endfor %} {% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if item.fields %}
|
||||
<h4>{% data ui.products.graphql.reference.fields %}</h4>
|
||||
{% assign fields = item.fields %}
|
||||
{% include graphql-fields %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,18 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
{% assign inputFields = item.inputFields %}
|
||||
{% assign returnFields = item.returnFields %}
|
||||
{% include graphql-input-fields %}
|
||||
{% include graphql-return-fields %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,29 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %} {% include graphql-deprecation %} {% if
|
||||
item.implements %}
|
||||
<h4>{% data ui.products.graphql.reference.implements %}</h4>
|
||||
<ul>
|
||||
{% for interface in item.implements %}
|
||||
<li>
|
||||
<code
|
||||
><a href="/{{ currentLanguage }}{{ interface.href }}"
|
||||
>{{ interface.name }}</a
|
||||
></code
|
||||
>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %} {% if item.fields %}
|
||||
<h4>{% data ui.products.graphql.reference.fields %}</h4>
|
||||
{% assign fields = item.fields %} {% include graphql-fields %} {% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +0,0 @@
|
||||
{% if item.preview %}
|
||||
<div class="extended-markdown note border rounded-1 mt-3 mb-4 p-3 color-border-accent-emphasis color-bg-accent f5">
|
||||
<p><b>{% data ui.products.graphql.reference.preview_notice %}</b></p>
|
||||
<p><code>{{ item.name }}</code> is available under the <a href="/{{ currentLanguage }}{{ item.preview.href }}">{{ item.preview.title }}</a>. During the preview period, the API may change without notice.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,19 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" aria-hidden tabindex="-1" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
<p>
|
||||
<b>{% data ui.products.graphql.reference.type %}:</b>
|
||||
<a href="/{{ currentLanguage }}{{ item.href }}">{{ item.type }}</a>
|
||||
</p>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %} {% include graphql-deprecation %} {% if item.args.size > 0 %}
|
||||
<h4>{% data ui.products.graphql.reference.arguments %}</h4>
|
||||
{% assign fields = item.args %} {% include graphql-fields %} {% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,22 +0,0 @@
|
||||
<h4>{% data ui.products.graphql.reference.return_fields %}</h4>
|
||||
<table class="fields width-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% data ui.products.graphql.reference.name %}</th>
|
||||
<th>{% data ui.products.graphql.reference.description %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for returnField in returnFields %}
|
||||
<tr>
|
||||
<td><p><code>{{ returnField.name }}</code> (<code><a href="/{{ currentLanguage }}{{ returnField.href }}">{{ returnField.type }}</a></code>)</p></td>
|
||||
<td>{% if returnField.description %}{{ returnField.description }}{% else %}N/A{% endif %}
|
||||
|
||||
{% assign item = returnField %}
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,12 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
|
||||
{{ item.description }}
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
<div>
|
||||
<div>
|
||||
<h2 id="{{ item.id }}">
|
||||
<a href="#{{ item.id }}" class="doctocat-link">{% include doctocat-link-icon %}</a>
|
||||
{{- item.name -}}
|
||||
</h2>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% include graphql-preview %}
|
||||
{% include graphql-deprecation %}
|
||||
|
||||
<h4>{% data ui.products.graphql.reference.possible_types %}</h4>
|
||||
<ul>
|
||||
{% for possibleType in item.possibleTypes %}
|
||||
<li><a href="/{{ currentLanguage }}{{ possibleType.href }}">{{ possibleType.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,8 +0,0 @@
|
||||
# Liquid Tags
|
||||
|
||||
This directory contains templates for our custom Liquid tags.
|
||||
|
||||
See also:
|
||||
|
||||
- [lib/liquid-tags/README.md](../../lib/liquid-tags/README.md)
|
||||
- [contributing/liquid-helpers.md](../../contributing/liquid-helpers.md)
|
||||
@@ -1 +0,0 @@
|
||||
{{ renderedReferenceWithIndent }}
|
||||
90
lib/graphql/index.js
Normal file
90
lib/graphql/index.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
readCompressedJsonFileFallbackLazily,
|
||||
readCompressedJsonFileFallback,
|
||||
} from '../../lib/read-json-file.js'
|
||||
import { getAutomatedPageMiniTocItems } from '../get-mini-toc-items.js'
|
||||
import languages from '../languages.js'
|
||||
import { allVersions } from '../all-versions.js'
|
||||
|
||||
/* ADD LANGUAGE KEY */
|
||||
let previews
|
||||
let upcomingChanges
|
||||
const changelog = new Map()
|
||||
const graphqlSchema = new Map()
|
||||
const miniTocs = new Map()
|
||||
|
||||
Object.keys(languages).forEach((language) => {
|
||||
miniTocs.set(language, new Map())
|
||||
})
|
||||
|
||||
export function getGraphqlSchema(version, type) {
|
||||
const graphqlVersion = getGraphqlVersion(version)
|
||||
if (!graphqlSchema.has(graphqlVersion)) {
|
||||
graphqlSchema.set(
|
||||
graphqlVersion,
|
||||
readCompressedJsonFileFallback(`lib/graphql/static/schema-${graphqlVersion}.json`)
|
||||
)
|
||||
}
|
||||
return graphqlSchema.get(graphqlVersion)[type]
|
||||
}
|
||||
|
||||
export function getGraphqlChangelog() {
|
||||
if (!changelog.has('schema')) {
|
||||
changelog.set(
|
||||
'schema',
|
||||
readCompressedJsonFileFallbackLazily('./lib/graphql/static/changelog.json')()
|
||||
)
|
||||
}
|
||||
|
||||
return changelog.get('schema')
|
||||
}
|
||||
|
||||
export function getGraphqlBreakingChanges(version) {
|
||||
const graphqlVersion = getGraphqlVersion(version)
|
||||
if (!upcomingChanges) {
|
||||
upcomingChanges = readCompressedJsonFileFallbackLazily(
|
||||
'./lib/graphql/static/upcoming-changes.json'
|
||||
)()
|
||||
}
|
||||
return upcomingChanges[graphqlVersion]
|
||||
}
|
||||
|
||||
export function getPreviews(version) {
|
||||
const graphqlVersion = getGraphqlVersion(version)
|
||||
if (!previews) {
|
||||
previews = readCompressedJsonFileFallbackLazily('./lib/graphql/static/previews.json')()
|
||||
}
|
||||
return previews[graphqlVersion]
|
||||
}
|
||||
|
||||
export async function getMiniToc(context, type, items, depth = 2, markdownHeading = '') {
|
||||
const { currentLanguage, currentVersion } = context
|
||||
const graphqlVersion = getGraphqlVersion(currentVersion)
|
||||
if (!miniTocs.get(currentLanguage).has(graphqlVersion)) {
|
||||
miniTocs.get(currentLanguage).set(graphqlVersion, new Map())
|
||||
}
|
||||
if (!miniTocs.get(currentLanguage).get(graphqlVersion).has(type)) {
|
||||
const graphqlMiniTocItems = await getAutomatedPageMiniTocItems(
|
||||
items,
|
||||
context,
|
||||
depth,
|
||||
markdownHeading
|
||||
)
|
||||
miniTocs.get(currentLanguage).get(graphqlVersion).set(type, graphqlMiniTocItems)
|
||||
}
|
||||
return miniTocs.get(currentLanguage).get(graphqlVersion).get(type)
|
||||
}
|
||||
|
||||
export async function getChangelogMiniTocs(items, context, depth = 2, markdownHeading = '') {
|
||||
if (!changelog.has('toc')) {
|
||||
changelog.set('toc', await getAutomatedPageMiniTocItems(items, context, depth, markdownHeading))
|
||||
}
|
||||
return changelog.get('toc')
|
||||
}
|
||||
|
||||
function getGraphqlVersion(version) {
|
||||
if (!(version in allVersions)) {
|
||||
throw new Error(`Unrecognized version '${version}'. Not found in ${Object.keys(allVersions)}`)
|
||||
}
|
||||
return allVersions[version].miscVersionName
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -90272,7 +90272,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -90292,7 +90292,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -90349,13 +90349,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -90368,7 +90368,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -73488,7 +73488,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -73508,7 +73508,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -73565,13 +73565,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -73584,7 +73584,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -90272,7 +90272,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -90292,7 +90292,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -90349,13 +90349,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -90368,7 +90368,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -73150,7 +73150,7 @@
|
||||
"scalars": [
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -73170,7 +73170,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -73227,13 +73227,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -73246,7 +73246,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -72887,7 +72887,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -72907,7 +72907,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -72964,13 +72964,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -72983,7 +72983,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -73735,7 +73735,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -73755,7 +73755,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -73812,13 +73812,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -73831,7 +73831,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -74968,7 +74968,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"description": "Represents `true` or `false` values.",
|
||||
"description": "<p>Represents <code>true</code> or <code>false</code> values.</p>",
|
||||
"id": "boolean",
|
||||
"href": "/graphql/reference/scalars#boolean"
|
||||
},
|
||||
@@ -74988,7 +74988,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Float",
|
||||
"description": "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).",
|
||||
"description": "<p>Represents signed double-precision fractional values as specified by <a href=\"https://en.wikipedia.org/wiki/IEEE_floating_point\">IEEE 754</a>.</p>",
|
||||
"id": "float",
|
||||
"href": "/graphql/reference/scalars#float"
|
||||
},
|
||||
@@ -75045,13 +75045,13 @@
|
||||
},
|
||||
{
|
||||
"name": "ID",
|
||||
"description": "Represents a unique identifier that is Base64 obfuscated. It is 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 `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.",
|
||||
"description": "<p>Represents a unique identifier that is Base64 obfuscated. It is 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 <code>\"VXNlci0xMA==\"</code>) or integer (such as <code>4</code>) input value will be accepted as an ID.</p>",
|
||||
"id": "id",
|
||||
"href": "/graphql/reference/scalars#id"
|
||||
},
|
||||
{
|
||||
"name": "Int",
|
||||
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
|
||||
"description": "<p>Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.</p>",
|
||||
"id": "int",
|
||||
"href": "/graphql/reference/scalars#int"
|
||||
},
|
||||
@@ -75064,7 +75064,7 @@
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.",
|
||||
"description": "<p>Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.</p>",
|
||||
"id": "string",
|
||||
"href": "/graphql/reference/scalars#string"
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@ const contentPath = path.join(process.cwd(), 'content/rest')
|
||||
|
||||
Example:
|
||||
{
|
||||
version: {
|
||||
[version]: {
|
||||
category: {
|
||||
subcategory: [operations],
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import {
|
||||
readCompressedJsonFileFallbackLazily,
|
||||
readCompressedJsonFileFallback,
|
||||
} from '../../lib/read-json-file.js'
|
||||
import { allVersions } from '../../lib/all-versions.js'
|
||||
const previews = readCompressedJsonFileFallbackLazily('./lib/graphql/static/previews.json')
|
||||
const upcomingChanges = readCompressedJsonFileFallbackLazily(
|
||||
'./lib/graphql/static/upcoming-changes.json'
|
||||
)
|
||||
const changelog = readCompressedJsonFileFallbackLazily('./lib/graphql/static/changelog.json')
|
||||
const prerenderedObjects = readCompressedJsonFileFallbackLazily(
|
||||
'./lib/graphql/static/prerendered-objects.json'
|
||||
)
|
||||
const prerenderedInputObjects = readCompressedJsonFileFallbackLazily(
|
||||
'./lib/graphql/static/prerendered-input-objects.json'
|
||||
)
|
||||
const prerenderedMutations = readCompressedJsonFileFallbackLazily(
|
||||
'./lib/graphql/static/prerendered-mutations.json'
|
||||
)
|
||||
|
||||
const explorerUrl =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? 'https://graphql.github.com/explorer'
|
||||
: 'http://localhost:3000'
|
||||
|
||||
const graphQLVersionSchemaCache = new Map()
|
||||
function readGraphQLVersionSchema(graphqlVersion) {
|
||||
if (!graphQLVersionSchemaCache.has(graphqlVersion)) {
|
||||
graphQLVersionSchemaCache.set(
|
||||
graphqlVersion,
|
||||
readCompressedJsonFileFallback(`lib/graphql/static/schema-${graphqlVersion}.json`)
|
||||
)
|
||||
}
|
||||
return graphQLVersionSchemaCache.get(graphqlVersion)
|
||||
}
|
||||
|
||||
export default function graphqlContext(req, res, next) {
|
||||
const currentVersionObj = allVersions[req.context.currentVersion]
|
||||
// ignore requests to non-GraphQL reference paths
|
||||
// and to versions that don't exist
|
||||
if (!req.pagePath.includes('/graphql/') || !currentVersionObj) {
|
||||
return next()
|
||||
}
|
||||
// Get the relevant name of the GraphQL schema files for the current version
|
||||
// For example, free-pro-team@latest corresponds to dotcom,
|
||||
// enterprise-server@2.22 corresponds to ghes-2.22,
|
||||
// and github-ae@latest corresponds to ghae
|
||||
const graphqlVersion = currentVersionObj.miscVersionName
|
||||
|
||||
req.context.graphql = {
|
||||
schemaForCurrentVersion: readGraphQLVersionSchema(graphqlVersion),
|
||||
previewsForCurrentVersion: previews()[graphqlVersion],
|
||||
upcomingChangesForCurrentVersion: upcomingChanges()[graphqlVersion],
|
||||
prerenderedObjectsForCurrentVersion: prerenderedObjects()[graphqlVersion],
|
||||
prerenderedInputObjectsForCurrentVersion: prerenderedInputObjects()[graphqlVersion],
|
||||
prerenderedMutationsForCurrentVersion: prerenderedMutations()[graphqlVersion],
|
||||
explorerUrl,
|
||||
changelog: changelog(),
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import categoriesForSupport from './categories-for-support.js'
|
||||
import triggerError from './trigger-error.js'
|
||||
import releaseNotes from './contextualizers/release-notes.js'
|
||||
import whatsNewChangelog from './contextualizers/whats-new-changelog.js'
|
||||
import graphQL from './contextualizers/graphql.js'
|
||||
import webhooks from './contextualizers/webhooks.js'
|
||||
import layout from './contextualizers/layout.js'
|
||||
import currentProductTree from './contextualizers/current-product-tree.js'
|
||||
@@ -282,7 +281,6 @@ export default function (app) {
|
||||
|
||||
// *** Preparation for render-page: contextualizers ***
|
||||
app.use(asyncMiddleware(instrument(releaseNotes, './contextualizers/release-notes')))
|
||||
app.use(instrument(graphQL, './contextualizers/graphql'))
|
||||
app.use(instrument(webhooks, './contextualizers/webhooks'))
|
||||
app.use(asyncMiddleware(instrument(whatsNewChangelog, './contextualizers/whats-new-changelog')))
|
||||
app.use(instrument(layout, './contextualizers/layout'))
|
||||
|
||||
@@ -24,21 +24,6 @@ async function buildRenderedPage(req) {
|
||||
|
||||
const renderedPage = await pageRenderTimed(context)
|
||||
|
||||
// handle special-case prerendered GraphQL objects page
|
||||
if (path.endsWith('graphql/reference/objects')) {
|
||||
return renderedPage + context.graphql.prerenderedObjectsForCurrentVersion.html
|
||||
}
|
||||
|
||||
// handle special-case prerendered GraphQL input objects page
|
||||
if (path.endsWith('graphql/reference/input-objects')) {
|
||||
return renderedPage + context.graphql.prerenderedInputObjectsForCurrentVersion.html
|
||||
}
|
||||
|
||||
// handle special-case prerendered GraphQL mutations page
|
||||
if (path.endsWith('graphql/reference/mutations')) {
|
||||
return renderedPage + context.graphql.prerenderedMutationsForCurrentVersion.html
|
||||
}
|
||||
|
||||
return renderedPage
|
||||
}
|
||||
|
||||
|
||||
61
pages/[versionId]/graphql/overview/breaking-changes.tsx
Normal file
61
pages/[versionId]/graphql/overview/breaking-changes.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
import { AutomatedPage } from 'components/article/AutomatedPage'
|
||||
import {
|
||||
AutomatedPageContext,
|
||||
AutomatedPageContextT,
|
||||
getAutomatedPageContextFromRequest,
|
||||
} from 'components/context/AutomatedPageContext'
|
||||
import { getAutomatedPageMiniTocItems } from 'lib/get-mini-toc-items.js'
|
||||
import { BreakingChanges } from 'components/graphql/BreakingChanges'
|
||||
import { BreakingChangesT } from 'components/graphql/types'
|
||||
import { getGraphqlBreakingChanges } from 'lib/graphql/index.js'
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
schema: BreakingChangesT
|
||||
automatedPageContext: AutomatedPageContextT
|
||||
}
|
||||
|
||||
export default function GraphqlBreakingChanges({
|
||||
mainContext,
|
||||
schema,
|
||||
automatedPageContext,
|
||||
}: Props) {
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<AutomatedPageContext.Provider value={automatedPageContext}>
|
||||
<AutomatedPage>
|
||||
<BreakingChanges schema={schema} />
|
||||
</AutomatedPage>
|
||||
</AutomatedPageContext.Provider>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
const currentVersion = context.query.versionId as string
|
||||
const schema = getGraphqlBreakingChanges(currentVersion)
|
||||
if (!schema) throw new Error(`No graphql breaking changes schema found for ${currentVersion}`)
|
||||
|
||||
// Gets the miniTocItems in the article context. At this point it will only
|
||||
// include miniTocItems that exist in Markdown pages in
|
||||
// content/graphql/reference/*
|
||||
const automatedPageContext = getAutomatedPageContextFromRequest(req)
|
||||
const titles = Object.keys(schema).map((item) => `Changes scheduled for ${item}`)
|
||||
const changelogMiniTocItems = await getAutomatedPageMiniTocItems(titles, req.context.context, 2)
|
||||
// Update the existing context to include the miniTocItems from GraphQL
|
||||
automatedPageContext.miniTocItems.push(...changelogMiniTocItems)
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: getMainContext(req, res),
|
||||
automatedPageContext,
|
||||
schema,
|
||||
},
|
||||
}
|
||||
}
|
||||
54
pages/[versionId]/graphql/overview/changelog.tsx
Normal file
54
pages/[versionId]/graphql/overview/changelog.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
import { AutomatedPage } from 'components/article/AutomatedPage'
|
||||
import {
|
||||
AutomatedPageContext,
|
||||
AutomatedPageContextT,
|
||||
getAutomatedPageContextFromRequest,
|
||||
} from 'components/context/AutomatedPageContext'
|
||||
import { getAutomatedPageMiniTocItems } from 'lib/get-mini-toc-items.js'
|
||||
import { Changelog } from 'components/graphql/Changelog'
|
||||
import { ChangelogItemT } from 'components/graphql/types'
|
||||
import { getGraphqlChangelog } from 'lib/graphql/index.js'
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
schema: ChangelogItemT[]
|
||||
automatedPageContext: AutomatedPageContextT
|
||||
}
|
||||
|
||||
export default function GraphqlChangelog({ mainContext, schema, automatedPageContext }: Props) {
|
||||
const content = <Changelog changelogItems={schema} />
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<AutomatedPageContext.Provider value={automatedPageContext}>
|
||||
<AutomatedPage>{content}</AutomatedPage>
|
||||
</AutomatedPageContext.Provider>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
const schema = getGraphqlChangelog() as ChangelogItemT[]
|
||||
if (!schema) throw new Error('No graphql free-pro-team changelog schema found.')
|
||||
// Gets the miniTocItems in the article context. At this point it will only
|
||||
// include miniTocItems that exist in Markdown pages in
|
||||
// content/graphql/reference/*
|
||||
const automatedPageContext = getAutomatedPageContextFromRequest(req)
|
||||
const titles = schema.map((item) => `Schema changes for ${item.date}`)
|
||||
const changelogMiniTocItems = await getAutomatedPageMiniTocItems(titles, req.context.context, 2)
|
||||
// Update the existing context to include the miniTocItems from GraphQL
|
||||
automatedPageContext.miniTocItems.push(...changelogMiniTocItems)
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: getMainContext(req, res),
|
||||
automatedPageContext,
|
||||
schema,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,15 @@ export default function GQLExplorer({ mainContext, graphqlExplorerUrl }: Props)
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
const graphqlExplorerUrl =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? 'https://graphql.github.com/explorer'
|
||||
: 'http://localhost:3000'
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: getMainContext(req, res),
|
||||
graphqlExplorerUrl: req.context.graphql.explorerUrl,
|
||||
graphqlExplorerUrl,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
56
pages/[versionId]/graphql/overview/schema-previews.tsx
Normal file
56
pages/[versionId]/graphql/overview/schema-previews.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
import { AutomatedPage } from 'components/article/AutomatedPage'
|
||||
import {
|
||||
AutomatedPageContext,
|
||||
AutomatedPageContextT,
|
||||
getAutomatedPageContextFromRequest,
|
||||
} from 'components/context/AutomatedPageContext'
|
||||
import { getAutomatedPageMiniTocItems } from 'lib/get-mini-toc-items.js'
|
||||
import { Previews } from 'components/graphql/Previews'
|
||||
import { PreviewT } from 'components/graphql/types'
|
||||
import { getPreviews } from 'lib/graphql/index.js'
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
schema: PreviewT[]
|
||||
automatedPageContext: AutomatedPageContextT
|
||||
}
|
||||
|
||||
export default function GraphqlPreviews({ mainContext, schema, automatedPageContext }: Props) {
|
||||
const content = <Previews schema={schema} />
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<AutomatedPageContext.Provider value={automatedPageContext}>
|
||||
<AutomatedPage>{content}</AutomatedPage>
|
||||
</AutomatedPageContext.Provider>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
const currentVersion = context.query.versionId as string
|
||||
const schema = getPreviews(currentVersion) as PreviewT[]
|
||||
if (!schema) throw new Error(`No graphql preview schema found for ${currentVersion}`)
|
||||
|
||||
// Gets the miniTocItems in the article context. At this point it will only
|
||||
// include miniTocItems that exist in Markdown pages in
|
||||
// content/graphql/reference/*
|
||||
const automatedPageContext = getAutomatedPageContextFromRequest(req)
|
||||
const titles = schema.map((item) => item.title)
|
||||
const changelogMiniTocItems = await getAutomatedPageMiniTocItems(titles, req.context.context, 2)
|
||||
// Update the existing context to include the miniTocItems from GraphQL
|
||||
automatedPageContext.miniTocItems.push(...changelogMiniTocItems)
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: getMainContext(req, res),
|
||||
automatedPageContext,
|
||||
schema,
|
||||
},
|
||||
}
|
||||
}
|
||||
91
pages/[versionId]/graphql/reference/[page].tsx
Normal file
91
pages/[versionId]/graphql/reference/[page].tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React from 'react'
|
||||
|
||||
import { GraphqlPage } from 'components/graphql/GraphqlPage'
|
||||
import { getGraphqlSchema, getMiniToc } from 'lib/graphql/index.js'
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
import type { ObjectT, QueryItemT, GraphqlT } from 'components/graphql/types'
|
||||
import { AutomatedPage } from 'components/article/AutomatedPage'
|
||||
import {
|
||||
AutomatedPageContext,
|
||||
AutomatedPageContextT,
|
||||
getAutomatedPageContextFromRequest,
|
||||
} from 'components/context/AutomatedPageContext'
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
automatedPageContext: AutomatedPageContextT
|
||||
schema: Object
|
||||
language: string
|
||||
graphqlPageName: string
|
||||
objects?: ObjectT[]
|
||||
}
|
||||
|
||||
export default function GraphqlReferencePage({
|
||||
mainContext,
|
||||
automatedPageContext,
|
||||
schema,
|
||||
graphqlPageName,
|
||||
objects,
|
||||
}: Props) {
|
||||
const content = (
|
||||
<GraphqlPage schema={schema} pageName={graphqlPageName} objects={objects || undefined} />
|
||||
)
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<AutomatedPageContext.Provider value={automatedPageContext}>
|
||||
<AutomatedPage>{content}</AutomatedPage>
|
||||
</AutomatedPageContext.Provider>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
const language = req.context.currentLanguage as string
|
||||
const currentVersion = req.context.currentVersion as string
|
||||
const page = context.query.page as string
|
||||
const graphqlPageName = page === 'input-objects' ? 'inputObjects' : page
|
||||
|
||||
const schema = getGraphqlSchema(currentVersion, graphqlPageName)
|
||||
// When the page is 'interfaces', we need to make another call to
|
||||
// get the objects page properties too.
|
||||
const objects =
|
||||
graphqlPageName === 'interfaces' ? getGraphqlSchema(currentVersion, 'objects') : null
|
||||
|
||||
// Gets the miniTocItems in the article context. At this point it will only
|
||||
// include miniTocItems that exist in Markdown pages in
|
||||
// content/graphql/reference/*
|
||||
const automatedPageContext = getAutomatedPageContextFromRequest(req)
|
||||
|
||||
if (graphqlPageName === 'queries') {
|
||||
const connectionItems = schema.connections.map((item: QueryItemT) => item.name)
|
||||
const connectionMiniToc = await getMiniToc(
|
||||
req.context,
|
||||
'connections',
|
||||
connectionItems,
|
||||
3,
|
||||
'## Connections\n'
|
||||
)
|
||||
const fieldItems = schema.fields.map((item: QueryItemT) => item.name)
|
||||
const fieldMiniToc = await getMiniToc(req.context, 'fields', fieldItems, 3, '## Fields\n')
|
||||
automatedPageContext.miniTocItems.push(...connectionMiniToc, ...fieldMiniToc)
|
||||
} else {
|
||||
const items = schema.map((item: GraphqlT) => item.name)
|
||||
const graphqlMiniTocItems = await getMiniToc(req.context, graphqlPageName, items)
|
||||
// Update the existing context to include the miniTocItems from GraphQL
|
||||
automatedPageContext.miniTocItems.push(...graphqlMiniTocItems)
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: getMainContext(req, res),
|
||||
automatedPageContext,
|
||||
schema,
|
||||
language,
|
||||
graphqlPageName,
|
||||
objects,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import { diff, ChangeType } from '@graphql-inspector/core'
|
||||
import { loadSchema } from '@graphql-tools/load'
|
||||
import fs from 'fs'
|
||||
import renderContent from '../../lib/render-content'
|
||||
|
||||
/**
|
||||
* Tag `changelogEntry` with `date: YYYY-mm-dd`, then prepend it to the JSON
|
||||
@@ -91,15 +92,27 @@ export async function createChangelogEntry(
|
||||
upcomingChanges: [],
|
||||
}
|
||||
|
||||
const cleanedSchemaChanges = cleanMessagesFromChanges(schemaChangesToReport)
|
||||
const renderedScheamChanges = await Promise.all(
|
||||
cleanedSchemaChanges.map(async (change) => {
|
||||
return await renderContent(change)
|
||||
})
|
||||
)
|
||||
const schemaChange = {
|
||||
title: 'The GraphQL schema includes these changes:',
|
||||
// Replace single quotes which wrap field/argument/type names with backticks
|
||||
changes: cleanMessagesFromChanges(schemaChangesToReport),
|
||||
changes: renderedScheamChanges,
|
||||
}
|
||||
changelogEntry.schemaChanges.push(schemaChange)
|
||||
|
||||
for (const previewTitle in previewChangesToReport) {
|
||||
const previewChanges = previewChangesToReport[previewTitle]
|
||||
const cleanedPreviewChanges = cleanMessagesFromChanges(previewChanges.changes)
|
||||
const renderedPreviewChanges = await Promise.all(
|
||||
cleanedPreviewChanges.map(async (change) => {
|
||||
return renderContent(change)
|
||||
})
|
||||
)
|
||||
const cleanTitle = cleanPreviewTitle(previewTitle)
|
||||
const entryTitle =
|
||||
'The [' +
|
||||
@@ -109,19 +122,25 @@ export async function createChangelogEntry(
|
||||
') includes these changes:'
|
||||
changelogEntry.previewChanges.push({
|
||||
title: entryTitle,
|
||||
changes: cleanMessagesFromChanges(previewChanges.changes),
|
||||
changes: renderedPreviewChanges,
|
||||
})
|
||||
}
|
||||
|
||||
if (addedUpcomingChanges.length > 0) {
|
||||
const cleanedUpcomingChanges = addedUpcomingChanges.map((change) => {
|
||||
const location = change.location
|
||||
const description = change.description
|
||||
const date = change.date.split('T')[0]
|
||||
return 'On member `' + location + '`:' + description + ' **Effective ' + date + '**.'
|
||||
})
|
||||
const renderedUpcomingChanges = await Promise.all(
|
||||
cleanedUpcomingChanges.map(async (change) => {
|
||||
return await renderContent(change)
|
||||
})
|
||||
)
|
||||
changelogEntry.upcomingChanges.push({
|
||||
title: 'The following changes will be made to the schema:',
|
||||
changes: addedUpcomingChanges.map(function (change) {
|
||||
const location = change.location
|
||||
const description = change.description
|
||||
const date = change.date.split('T')[0]
|
||||
return 'On member `' + location + '`:' + description + ' **Effective ' + date + '**.'
|
||||
}),
|
||||
changes: renderedUpcomingChanges,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import { allVersions } from '../../lib/all-versions.js'
|
||||
import processPreviews from './utils/process-previews.js'
|
||||
import processUpcomingChanges from './utils/process-upcoming-changes.js'
|
||||
import processSchemas from './utils/process-schemas.js'
|
||||
import prerender from './utils/prerender-graphql.js'
|
||||
import { prependDatedEntry, createChangelogEntry } from './build-changelog.js'
|
||||
import loadData from '../../lib/site-data.js'
|
||||
|
||||
@@ -33,9 +32,6 @@ main()
|
||||
async function main() {
|
||||
const previewsJson = {}
|
||||
const upcomingChangesJson = {}
|
||||
const prerenderedObjects = {}
|
||||
const prerenderedInputObjects = {}
|
||||
const prerenderedMutations = {}
|
||||
|
||||
const siteData = loadData()
|
||||
|
||||
@@ -81,26 +77,7 @@ async function main() {
|
||||
context.graphql = { schemaForCurrentVersion: schemaJsonPerVersion }
|
||||
context.currentVersion = version
|
||||
|
||||
// 4. PRERENDER OBJECTS HTML
|
||||
// because the objects page is too big to render on page load
|
||||
prerenderedObjects[graphqlVersion] = await prerender(context, 'objects', 'graphql-object.html')
|
||||
|
||||
// 5. PRERENDER INPUT OBJECTS HTML
|
||||
// because the objects page is too big to render on page load
|
||||
prerenderedInputObjects[graphqlVersion] = await prerender(
|
||||
context,
|
||||
'inputObjects',
|
||||
'graphql-input-object.html'
|
||||
)
|
||||
|
||||
// Prerender mutations
|
||||
prerenderedMutations[graphqlVersion] = await prerender(
|
||||
context,
|
||||
'mutations',
|
||||
'graphql-mutation.html'
|
||||
)
|
||||
|
||||
// 6. UPDATE CHANGELOG
|
||||
// 4. UPDATE CHANGELOG
|
||||
if (allVersions[version].nonEnterpriseDefault) {
|
||||
// The Changelog is only build for free-pro-team@latest
|
||||
const changelogEntry = await createChangelogEntry(
|
||||
@@ -121,18 +98,6 @@ async function main() {
|
||||
|
||||
await updateStaticFile(previewsJson, path.join(graphqlStaticDir, 'previews.json'))
|
||||
await updateStaticFile(upcomingChangesJson, path.join(graphqlStaticDir, 'upcoming-changes.json'))
|
||||
await updateStaticFile(
|
||||
prerenderedObjects,
|
||||
path.join(graphqlStaticDir, 'prerendered-objects.json')
|
||||
)
|
||||
await updateStaticFile(
|
||||
prerenderedInputObjects,
|
||||
path.join(graphqlStaticDir, 'prerendered-input-objects.json')
|
||||
)
|
||||
await updateStaticFile(
|
||||
prerenderedMutations,
|
||||
path.join(graphqlStaticDir, 'prerendered-mutations.json')
|
||||
)
|
||||
|
||||
// Ensure the YAML linter runs before checkinging in files
|
||||
execSync('npx prettier -w "**/*.{yml,yaml}"')
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import cheerio from 'cheerio'
|
||||
import { liquid } from '../../../lib/render-content/index.js'
|
||||
import getMiniTocItems from '../../../lib/get-mini-toc-items.js'
|
||||
import rewriteLocalLinks from '../../../lib/rewrite-local-links.js'
|
||||
const includes = path.join(process.cwd(), 'includes')
|
||||
|
||||
export default async function prerender(context, type, includeFilename) {
|
||||
const htmlArray = []
|
||||
|
||||
const includeFile = await fs.readFile(path.join(includes, includeFilename), 'utf8')
|
||||
// render the layout for every object
|
||||
for (const item of context.graphql.schemaForCurrentVersion[type]) {
|
||||
context.item = item
|
||||
const itemHtml = await liquid.parseAndRender(includeFile, context)
|
||||
const $ = cheerio.load(itemHtml, { xmlMode: true })
|
||||
rewriteLocalLinks($, context.currentVersion, context.currentLanguage)
|
||||
const htmlWithVersionedLinks = $.html()
|
||||
htmlArray.push(htmlWithVersionedLinks)
|
||||
}
|
||||
|
||||
const html = htmlArray.join('\n')
|
||||
|
||||
return {
|
||||
html,
|
||||
miniToc: getMiniTocItems(html),
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import cheerio from 'cheerio'
|
||||
import { liquid } from '../../../lib/render-content/index.js'
|
||||
import getMiniTocItems from '../../../lib/get-mini-toc-items.js'
|
||||
import rewriteLocalLinks from '../../../lib/rewrite-local-links.js'
|
||||
const includes = path.join(process.cwd(), 'includes')
|
||||
const inputObjectIncludeFile = await fs.readFile(
|
||||
path.join(includes, 'graphql-input-object.html'),
|
||||
'utf8'
|
||||
)
|
||||
|
||||
export default async function prerenderInputObjects(context) {
|
||||
const inputObjectsArray = []
|
||||
|
||||
// render the graphql-object.html layout for every object
|
||||
for (const inputObject of context.graphql.schemaForCurrentVersion.inputObjects) {
|
||||
context.item = inputObject
|
||||
const inputObjectHtml = await liquid.parseAndRender(inputObjectIncludeFile, context)
|
||||
const $ = cheerio.load(inputObjectHtml, { xmlMode: true })
|
||||
rewriteLocalLinks($, context.currentVersion, context.currentLanguage)
|
||||
const htmlWithVersionedLinks = $.html()
|
||||
inputObjectsArray.push(htmlWithVersionedLinks)
|
||||
}
|
||||
|
||||
const inputObjectsHtml = inputObjectsArray.join('\n')
|
||||
|
||||
return {
|
||||
html: inputObjectsHtml,
|
||||
miniToc: getMiniTocItems(inputObjectsHtml),
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import cheerio from 'cheerio'
|
||||
import { liquid } from '../../../lib/render-content/index.js'
|
||||
import getMiniTocItems from '../../../lib/get-mini-toc-items.js'
|
||||
import rewriteLocalLinks from '../../../lib/rewrite-local-links.js'
|
||||
const includes = path.join(process.cwd(), 'includes')
|
||||
const objectIncludeFile = await fs.readFile(path.join(includes, 'graphql-object.html'), 'utf8')
|
||||
|
||||
export default async function prerenderObjects(context) {
|
||||
const objectsArray = []
|
||||
|
||||
// render the graphql-object.html layout for every object
|
||||
for (const object of context.graphql.schemaForCurrentVersion.objects) {
|
||||
context.item = object
|
||||
const objectHtml = await liquid.parseAndRender(objectIncludeFile, context)
|
||||
const $ = cheerio.load(objectHtml, { xmlMode: true })
|
||||
rewriteLocalLinks($, context.currentVersion, context.currentLanguage)
|
||||
const htmlWithVersionedLinks = $.html()
|
||||
objectsArray.push(htmlWithVersionedLinks)
|
||||
}
|
||||
|
||||
const objectsHtml = objectsArray.join('\n')
|
||||
|
||||
return {
|
||||
html: objectsHtml,
|
||||
miniToc: getMiniTocItems(objectsHtml),
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,17 @@ import helpers from './schema-helpers.js'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
const externalScalars = JSON.parse(
|
||||
const externalScalarsJSON = JSON.parse(
|
||||
await fs.readFile(path.join(process.cwd(), './lib/graphql/non-schema-scalars.json'))
|
||||
).map((scalar) => {
|
||||
scalar.id = helpers.getId(scalar.name)
|
||||
scalar.href = helpers.getFullLink('scalars', scalar.id)
|
||||
return scalar
|
||||
})
|
||||
)
|
||||
const externalScalars = await Promise.all(
|
||||
externalScalarsJSON.map(async (scalar) => {
|
||||
scalar.description = await helpers.getDescription(scalar.description)
|
||||
scalar.id = helpers.getId(scalar.name)
|
||||
scalar.href = helpers.getFullLink('scalars', scalar.id)
|
||||
return scalar
|
||||
})
|
||||
)
|
||||
|
||||
// select and format all the data from the schema that we need for the docs
|
||||
// used in the build step by script/graphql/build-static-files.js
|
||||
|
||||
@@ -10,7 +10,6 @@ import { jest } from '@jest/globals'
|
||||
|
||||
const previewsJson = readJsonFile('./lib/graphql/static/previews.json')
|
||||
const upcomingChangesJson = readJsonFile('./lib/graphql/static/upcoming-changes.json')
|
||||
const prerenderedObjectsJson = readJsonFile('./lib/graphql/static/prerendered-objects.json')
|
||||
const allVersionValues = Object.values(allVersions)
|
||||
const graphqlVersions = allVersionValues.map((v) => v.miscVersionName)
|
||||
const graphqlTypes = readJsonFile('./lib/graphql/types.json').map((t) => t.kind)
|
||||
@@ -22,7 +21,6 @@ describe('graphql json files', () => {
|
||||
graphqlVersions.forEach((version) => {
|
||||
expect(version in previewsJson).toBe(true)
|
||||
expect(version in upcomingChangesJson).toBe(true)
|
||||
expect(version in prerenderedObjectsJson).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -86,26 +84,4 @@ describe('graphql json files', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('prerendered objects validation', () => {
|
||||
graphqlVersions.forEach((version) => {
|
||||
// TODO: Is this still true?
|
||||
//
|
||||
// shape of prerenderedObject: {
|
||||
// html: <div>foo</div>,
|
||||
// miniToc: {contents: '<a>bar</a>', headingLevel: N, indentationLevel: N}
|
||||
// }
|
||||
const prerenderedHtml = prerenderedObjectsJson[version].html
|
||||
expect(typeof prerenderedHtml).toBe('string')
|
||||
expect(prerenderedHtml.startsWith('<div>')).toBe(true)
|
||||
const prerenderedMiniToc = prerenderedObjectsJson[version].miniToc
|
||||
expect(Array.isArray(prerenderedMiniToc)).toBe(true)
|
||||
expect(prerenderedMiniToc.length).toBeGreaterThan(0)
|
||||
expect(typeof prerenderedMiniToc[0].contents).toBe('object')
|
||||
|
||||
// TODO: Check whether the following should be removed or updated.
|
||||
// expect(typeof prerenderedMiniToc[0].headingLevel).toBe('number')
|
||||
// expect(typeof prerenderedMiniToc[0].indentationLevel).toBe('number')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
16
tests/fixtures/changelog-entry.json
vendored
16
tests/fixtures/changelog-entry.json
vendored
@@ -2,8 +2,8 @@
|
||||
"previewChanges": [
|
||||
{
|
||||
"changes": [
|
||||
"Type for argument `changeTypeArgument` on field 'PreviewType.field1` changed from `Int` to `Float'",
|
||||
"Field `Query.previewField` changed type from `PreviewType` to `PreviewType!`"
|
||||
"<p>Type for argument <code>changeTypeArgument</code> on field 'PreviewType.field1<code>changed from</code>Int<code>to</code>Float'</p>",
|
||||
"<p>Field <code>Query.previewField</code> changed type from <code>PreviewType</code> to <code>PreviewType!</code></p>"
|
||||
],
|
||||
"title": "The [Test preview](/graphql/overview/schema-previews#test-preview) includes these changes:"
|
||||
}
|
||||
@@ -11,11 +11,11 @@
|
||||
"schemaChanges": [
|
||||
{
|
||||
"changes": [
|
||||
"Field `removedField` was removed from object type `Query`",
|
||||
"Argument `removedRequiredArgument: Int!` was removed from field `Query.argumentsField`",
|
||||
"Argument `removedOptionalArgument: Int!` was removed from field `Query.argumentsField`",
|
||||
"Type for argument `argumentMadeRequired` on field `Query.argumentsField` changed from `Int` to `Int!`",
|
||||
"Type for argument `argumentMadeOptional` on field `Query.argumentsField` changed from `Int!` to `Int`"
|
||||
"<p>Field <code>removedField</code> was removed from object type <code>Query</code></p>",
|
||||
"<p>Argument <code>removedRequiredArgument: Int!</code> was removed from field <code>Query.argumentsField</code></p>",
|
||||
"<p>Argument <code>removedOptionalArgument: Int!</code> was removed from field <code>Query.argumentsField</code></p>",
|
||||
"<p>Type for argument <code>argumentMadeRequired</code> on field <code>Query.argumentsField</code> changed from <code>Int</code> to <code>Int!</code></p>",
|
||||
"<p>Type for argument <code>argumentMadeOptional</code> on field <code>Query.argumentsField</code> changed from <code>Int!</code> to <code>Int</code></p>"
|
||||
],
|
||||
"title": "The GraphQL schema includes these changes:"
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
"upcomingChanges": [
|
||||
{
|
||||
"changes": [
|
||||
"On member `Query.stableField`:`stableField` will be removed. **Effective 2021-06-01**."
|
||||
"<p>On member <code>Query.stableField</code>:<code>stableField</code> will be removed. <strong>Effective 2021-06-01</strong>.</p>"
|
||||
],
|
||||
"title": "The following changes will be made to the schema:"
|
||||
}
|
||||
|
||||
41
tests/unit/graphql.js
Normal file
41
tests/unit/graphql.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { describe } from '@jest/globals'
|
||||
import { readFileSync } from 'fs'
|
||||
import { allVersions } from '../../lib/all-versions.js'
|
||||
import {
|
||||
getGraphqlSchema,
|
||||
getGraphqlChangelog,
|
||||
getGraphqlBreakingChanges,
|
||||
getPreviews,
|
||||
} from '../../lib/graphql/index.js'
|
||||
|
||||
describe('graphql schema', () => {
|
||||
const graphqlTypes = JSON.parse(readFileSync('lib/graphql/types.json')).map((item) => item.kind)
|
||||
for (const version in allVersions) {
|
||||
for (const type of graphqlTypes) {
|
||||
test(`getting the GraphQL ${type} schema works for ${version}`, async () => {
|
||||
const schema = getGraphqlSchema(version, type)
|
||||
expect(schema).toBeDefined()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
test('getting the graphql changelog works for dotcom', async () => {
|
||||
const defaultVersion = allVersions.defaultVersion
|
||||
const schema = getGraphqlChangelog(defaultVersion)
|
||||
expect(schema).toBeDefined()
|
||||
})
|
||||
|
||||
test('getting the graphql breaking changes works for every version', async () => {
|
||||
for (const version in allVersions) {
|
||||
const schema = getGraphqlBreakingChanges(version)
|
||||
expect(schema).toBeDefined()
|
||||
}
|
||||
})
|
||||
|
||||
test('getting the graphql previews works for every version', async () => {
|
||||
for (const version in allVersions) {
|
||||
const schema = getPreviews(version)
|
||||
expect(schema).toBeDefined()
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -4,14 +4,12 @@ import cheerio from 'cheerio'
|
||||
import { describe, expect } from '@jest/globals'
|
||||
|
||||
import Page from '../../lib/page.js'
|
||||
import readJsonFile from '../../lib/read-json-file.js'
|
||||
import { allVersions } from '../../lib/all-versions.js'
|
||||
import enterpriseServerReleases, { latest } from '../../lib/enterprise-server-releases.js'
|
||||
import nonEnterpriseDefaultVersion from '../../lib/non-enterprise-default-version.js'
|
||||
import loadSiteData from '../../lib/site-data.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const prerenderedObjects = readJsonFile('./lib/graphql/static/prerendered-objects.json')
|
||||
const enterpriseServerVersions = Object.keys(allVersions).filter((v) =>
|
||||
v.startsWith('enterprise-server@')
|
||||
)
|
||||
@@ -144,18 +142,6 @@ describe('Page class', () => {
|
||||
expect(last.attr('href')).toBe('/en/enterprise-server@3.2')
|
||||
})
|
||||
|
||||
test('rewrites links on prerendered GraphQL page include the current language prefix and version', async () => {
|
||||
const graphqlVersion =
|
||||
allVersions[`enterprise-server@${enterpriseServerReleases.latest}`].miscVersionName
|
||||
const $ = cheerio.load(prerenderedObjects[graphqlVersion].html)
|
||||
expect($('a[href^="/graphql/reference/input-objects"]').length).toBe(0)
|
||||
expect(
|
||||
$(
|
||||
`a[href^="/en/enterprise-server@${enterpriseServerReleases.latest}/graphql/reference/input-objects"]`
|
||||
).length
|
||||
).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
test('rewrites links in the intro to include the current language prefix and version', async () => {
|
||||
const page = await Page.init(opts)
|
||||
page.rawIntro =
|
||||
|
||||
Reference in New Issue
Block a user