chore: passing versions tests

This commit is contained in:
James
2023-09-23 10:07:29 -07:00
parent e5ef842839
commit a458375934
24 changed files with 286 additions and 100 deletions

View File

@@ -0,0 +1,63 @@
import type { CreateGlobalVersion } from 'payload/database'
import type { PayloadRequest } from 'payload/types'
import type { Document } from 'payload/types'
import type { MongooseAdapter } from '.'
import { withSession } from './withSession'
export const createGlobalVersion: CreateGlobalVersion = async function createGlobalVersion(
this: MongooseAdapter,
{ autosave, createdAt, globalSlug, parent, req = {} as PayloadRequest, updatedAt, versionData },
) {
const VersionModel = this.versions[globalSlug]
const options = withSession(this, req.transactionID)
const [doc] = await VersionModel.create(
[
{
autosave,
createdAt,
latest: true,
parent,
updatedAt,
version: versionData,
},
],
options,
req,
)
await VersionModel.updateMany(
{
$and: [
{
_id: {
$ne: doc._id,
},
},
{
parent: {
$eq: parent,
},
},
{
latest: {
$eq: true,
},
},
],
},
{ $unset: { latest: 1 } },
)
const result: Document = JSON.parse(JSON.stringify(doc))
const verificationToken = doc._verificationToken
// custom id type reset
result.id = result._id
if (verificationToken) {
result._verificationToken = verificationToken
}
return result
}

View File

@@ -11,6 +11,7 @@ import type { CollectionModel, GlobalModel } from './types'
import { connect } from './connect'
import { create } from './create'
import { createGlobal } from './createGlobal'
import { createGlobalVersion } from './createGlobalVersion'
import { createVersion } from './createVersion'
import { deleteMany } from './deleteMany'
import { deleteOne } from './deleteOne'
@@ -80,6 +81,7 @@ export function mongooseAdapter({
connection: undefined,
create,
createGlobal,
createGlobalVersion,
createMigration,
createVersion,
defaultIDType: 'text',

View File

@@ -0,0 +1,45 @@
import type { CreateGlobalVersion } from 'payload/database'
import type { PayloadRequest } from 'payload/types'
import { sql } from 'drizzle-orm'
import { buildVersionGlobalFields } from 'payload/versions'
import toSnakeCase from 'to-snake-case'
import type { PostgresAdapter } from './types'
import { upsertRow } from './upsertRow'
export const createGlobalVersion: CreateGlobalVersion = async function createGlobalVersion(
this: PostgresAdapter,
{ autosave, globalSlug, req = {} as PayloadRequest, versionData },
) {
const db = this.sessions?.[req.transactionID] || this.db
const global = this.payload.globals.config.find(({ slug }) => slug === globalSlug)
const globalTableName = toSnakeCase(globalSlug)
const tableName = `_${globalTableName}_versions`
const result = await upsertRow({
adapter: this,
data: {
autosave,
latest: true,
version: versionData,
},
db,
fields: buildVersionGlobalFields(global),
operation: 'create',
tableName,
})
const table = this.tables[tableName]
if (global.versions.drafts) {
await db.execute(sql`
UPDATE ${table}
SET latest = false
WHERE ${table.id} != ${result.id};
`)
}
return result
}

View File

@@ -7,6 +7,7 @@ import type { Args, PostgresAdapter, PostgresAdapterResult } from './types'
import { connect } from './connect'
import { create } from './create'
import { createGlobal } from './createGlobal'
import { createGlobalVersion } from './createGlobalVersion'
import { createMigration } from './createMigration'
import { createVersion } from './createVersion'
import { deleteMany } from './deleteMany'
@@ -32,8 +33,6 @@ import { webpack } from './webpack'
export function postgresAdapter(args: Args): PostgresAdapterResult {
function adapter({ payload }: { payload: Payload }) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return createDatabaseAdapter<PostgresAdapter>({
...args,
beginTransaction,
@@ -42,6 +41,7 @@ export function postgresAdapter(args: Args): PostgresAdapterResult {
connect,
create,
createGlobal,
createGlobalVersion,
createMigration,
createVersion,
db: undefined,
@@ -62,6 +62,7 @@ export function postgresAdapter(args: Args): PostgresAdapterResult {
queryDrafts,
relations: {},
rollbackTransaction,
schema: {},
sessions: {},
tables: {},
updateGlobal,

View File

@@ -3,7 +3,7 @@ import type { SanitizedConfig } from 'payload/config'
import type { Field, TypeWithID } from 'payload/types'
import { createBlocksMap } from '../../utilities/createBlocksMap'
import { createPathMap } from '../../utilities/createPathMap'
import { createPathMap } from '../../utilities/createRelationshipMap'
import { traverseFields } from './traverseFields'
type TransformArgs = {

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
export { BeginTransaction, CommitTransaction, Connect, Create, CreateArgs, CreateGlobal, CreateGlobalArgs, CreateMigration, CreateVersion, CreateVersionArgs, DatabaseAdapter, DeleteMany, DeleteManyArgs, DeleteOne, DeleteOneArgs, DeleteVersions, DeleteVersionsArgs, Destroy, Find, FindArgs, FindGlobal, FindGlobalArgs, FindGlobalVersions, FindGlobalVersionsArgs, FindOne, FindOneArgs, FindVersions, FindVersionsArgs, Init, Migration, MigrationData, PaginatedDocs, QueryDrafts, QueryDraftsArgs, RollbackTransaction, Transaction, UpdateGlobal, UpdateGlobalArgs, UpdateOne, UpdateOneArgs, UpdateVersion, UpdateVersionArgs, Webpack, } from './dist/database/types';
export { BeginTransaction, CommitTransaction, Connect, Create, CreateArgs, CreateGlobal, CreateGlobalArgs, CreateGlobalVersion, CreateGlobalVersionArgs, CreateMigration, CreateVersion, CreateVersionArgs, DatabaseAdapter, DeleteMany, DeleteManyArgs, DeleteOne, DeleteOneArgs, DeleteVersions, DeleteVersionsArgs, Destroy, Find, FindArgs, FindGlobal, FindGlobalArgs, FindGlobalVersions, FindGlobalVersionsArgs, FindOne, FindOneArgs, FindVersions, FindVersionsArgs, Init, Migration, MigrationData, PaginatedDocs, QueryDrafts, QueryDraftsArgs, RollbackTransaction, Transaction, UpdateGlobal, UpdateGlobalArgs, UpdateOne, UpdateOneArgs, UpdateVersion, UpdateVersionArgs, Webpack, } from './dist/database/types';
export * from './dist/database/queryValidation/types';
export { combineQueries } from './dist/database/combineQueries';
export { createDatabaseAdapter } from './dist/database/createDatabaseAdapter';

File diff suppressed because one or more lines are too long

View File

@@ -51,6 +51,7 @@ const getExecuteStaticAccess =
const doc = await req.payload.db.findOne({
collection: config.slug,
req,
where: queryToBuild,
})

View File

@@ -73,6 +73,7 @@ async function forgotPassword(incomingArgs: Arguments): Promise<null | string> {
let user = await payload.db.findOne<UserDoc>({
collection: collectionConfig.slug,
req,
where: { email: { equals: data.email.toLowerCase() } },
})

View File

@@ -1,13 +1,11 @@
import type { PayloadRequest } from '../../express/types'
async function init(args: { collection: string; req: PayloadRequest }): Promise<boolean> {
const {
collection: slug,
req: { payload },
} = args
const { collection: slug, req } = args
const doc = await payload.db.findOne({
const doc = await req.payload.db.findOne({
collection: slug,
req,
})
return !!doc

View File

@@ -19,6 +19,7 @@ async function verifyEmail(args: Args): Promise<boolean> {
const user = await req.payload.db.findOne<any>({
collection: collection.config.slug,
req,
where: {
_verificationToken: { equals: token },
},

View File

@@ -122,6 +122,7 @@ async function updateByID<TSlug extends keyof GeneratedTypes['collections']>(
const findOneArgs: FindOneArgs = {
collection: collectionConfig.slug,
locale,
req,
where: combineQueries({ id: { equals: id } }, accessResults),
}

View File

@@ -27,6 +27,7 @@ export interface DatabaseAdapter {
createGlobal: CreateGlobal
// migrations
createGlobalVersion: CreateGlobalVersion
/**
* Output a migration file
*/
@@ -166,7 +167,7 @@ export type QueryDraftsArgs = {
locale?: string
page?: number
pagination?: boolean
req?: PayloadRequest
req: PayloadRequest
sort?: string
where?: Where
}
@@ -176,7 +177,7 @@ export type QueryDrafts = <T = TypeWithID>(args: QueryDraftsArgs) => Promise<Pag
export type FindOneArgs = {
collection: string
locale?: string
req?: PayloadRequest
req: PayloadRequest
where?: Where
}
@@ -189,7 +190,7 @@ export type FindArgs = {
locale?: string
page?: number
pagination?: boolean
req?: PayloadRequest
req: PayloadRequest
skip?: number
sort?: string
versions?: boolean
@@ -203,7 +204,7 @@ type BaseVersionArgs = {
locale?: string
page?: number
pagination?: boolean
req?: PayloadRequest
req: PayloadRequest
skip?: number
sort?: string
versions?: boolean
@@ -224,7 +225,7 @@ export type FindGlobalVersionsArgs = BaseVersionArgs & {
export type FindGlobalArgs = {
locale?: string
req?: PayloadRequest
req: PayloadRequest
slug: string
where?: Where
}
@@ -232,7 +233,7 @@ export type FindGlobalArgs = {
export type UpdateGlobalVersionArgs<T = TypeWithID> = {
global: string
locale?: string
req?: PayloadRequest
req: PayloadRequest
versionData: T
} & (
| {
@@ -242,7 +243,8 @@ export type UpdateGlobalVersionArgs<T = TypeWithID> = {
| {
id?: never
where: Where
})
}
)
export type UpdateGlobalVersion = <T = TypeWithID>(
args: UpdateGlobalVersionArgs<T>,
@@ -252,7 +254,7 @@ export type FindGlobal = <T extends GlobalsTypeWithID = any>(args: FindGlobalArg
export type CreateGlobalArgs<T extends GlobalsTypeWithID = any> = {
data: T
req?: PayloadRequest
req: PayloadRequest
slug: string
}
export type CreateGlobal = <T extends GlobalsTypeWithID = any>(
@@ -261,7 +263,7 @@ export type CreateGlobal = <T extends GlobalsTypeWithID = any>(
export type UpdateGlobalArgs<T extends GlobalsTypeWithID = any> = {
data: T
req?: PayloadRequest
req: PayloadRequest
slug: string
}
export type UpdateGlobal = <T extends GlobalsTypeWithID = any>(
@@ -276,7 +278,7 @@ export type FindGlobalVersions = <T = TypeWithID>(
export type DeleteVersionsArgs = {
collection: string
locale?: string
req?: PayloadRequest
req: PayloadRequest
sort?: {
[key: string]: string
}
@@ -289,7 +291,7 @@ export type CreateVersionArgs<T = TypeWithID> = {
createdAt: string
/** ID of the parent document for which the version should be created for */
parent: number | string
req?: PayloadRequest
req: PayloadRequest
updatedAt: string
versionData: T
}
@@ -298,12 +300,27 @@ export type CreateVersion = <T = TypeWithID>(
args: CreateVersionArgs<T>,
) => Promise<TypeWithVersion<T>>
export type CreateGlobalVersionArgs<T = TypeWithID> = {
autosave: boolean
createdAt: string
globalSlug: string
/** ID of the parent document for which the version should be created for */
parent: number | string
req: PayloadRequest
updatedAt: string
versionData: T
}
export type CreateGlobalVersion = <T = TypeWithID>(
args: CreateGlobalVersionArgs<T>,
) => Promise<TypeWithVersion<T>>
export type DeleteVersions = (args: DeleteVersionsArgs) => Promise<void>
export type UpdateVersionArgs<T = TypeWithID> = {
collection: string
locale?: string
req?: PayloadRequest
req: PayloadRequest
versionData: T
} & (
| {
@@ -313,7 +330,8 @@ export type UpdateVersionArgs<T = TypeWithID> = {
| {
id?: never
where: Where
})
}
)
export type UpdateVersion = <T = TypeWithID>(
args: UpdateVersionArgs<T>,
@@ -324,7 +342,7 @@ export type CreateArgs = {
data: Record<string, unknown>
draft?: boolean
locale?: string
req?: PayloadRequest
req: PayloadRequest
}
export type Create = (args: CreateArgs) => Promise<Document>
@@ -334,7 +352,7 @@ export type UpdateOneArgs = {
data: Record<string, unknown>
draft?: boolean
locale?: string
req?: PayloadRequest
req: PayloadRequest
} & (
| {
id: number | string
@@ -350,7 +368,7 @@ export type UpdateOne = (args: UpdateOneArgs) => Promise<Document>
export type DeleteOneArgs = {
collection: string
req?: PayloadRequest
req: PayloadRequest
where: Where
}
@@ -358,7 +376,7 @@ export type DeleteOne = (args: DeleteOneArgs) => Promise<Document>
export type DeleteManyArgs = {
collection: string
req?: PayloadRequest
req: PayloadRequest
where: Where
}

View File

@@ -6,6 +6,8 @@ export {
CreateArgs,
CreateGlobal,
CreateGlobalArgs,
CreateGlobalVersion,
CreateGlobalVersionArgs,
CreateMigration,
CreateVersion,
CreateVersionArgs,

View File

@@ -88,11 +88,13 @@ function initGlobalsGraphQL(payload: Payload): void {
}
if (global.versions) {
const idType = payload.db.defaultIDType === 'number' ? GraphQLInt : GraphQLString
const versionGlobalFields: Field[] = [
...buildVersionGlobalFields(global),
{
name: 'id',
type: 'text',
type: payload.db.defaultIDType as 'text',
},
{
name: 'createdAt',
@@ -116,7 +118,7 @@ function initGlobalsGraphQL(payload: Payload): void {
payload.Query.fields[`version${formatName(formattedName)}`] = {
args: {
id: { type: GraphQLString },
id: { type: idType },
...(payload.config.localization
? {
fallbackLocale: { type: payload.types.fallbackLocaleInputType },
@@ -155,7 +157,7 @@ function initGlobalsGraphQL(payload: Payload): void {
}
payload.Mutation.fields[`restoreVersion${formatName(formattedName)}`] = {
args: {
id: { type: GraphQLString },
id: { type: idType },
},
resolve: restoreVersionResolver(global),
type: payload.globals.graphQL[slug].type,

View File

@@ -72,6 +72,7 @@ async function restoreVersion<T extends TypeWithVersion<T> = any>(args: Argument
// /////////////////////////////////////
const global = await payload.db.findGlobal({
req,
slug: globalConfig.slug,
})
@@ -80,11 +81,13 @@ async function restoreVersion<T extends TypeWithVersion<T> = any>(args: Argument
if (global) {
result = await payload.db.updateGlobal({
data: result,
req,
slug: globalConfig.slug,
})
} else {
result = await payload.db.createGlobal({
data: result,
req,
slug: globalConfig.slug,
})
}

View File

@@ -1,13 +1,16 @@
import type { Payload } from '..'
import type { PayloadRequest } from '../express/types'
const docWithFilenameExists = async (
payload: Payload,
collectionSlug: string,
path: string,
filename: string,
): Promise<boolean> => {
const doc = await payload.db.findOne({
type Args = {
collectionSlug: string
filename: string
path: string
req: PayloadRequest
}
const docWithFilenameExists = async ({ collectionSlug, filename, req }: Args): Promise<boolean> => {
const doc = await req.payload.db.findOne({
collection: collectionSlug,
req,
where: {
filename: {
equals: filename,

View File

@@ -143,7 +143,12 @@ export const generateFileData = async <T>({
fsSafeName = `${baseFilename}${ext ? `.${ext}` : ''}`
if (!overwriteExistingFiles) {
fsSafeName = await getSafeFileName(req.payload, collectionConfig.slug, staticPath, fsSafeName)
fsSafeName = await getSafeFileName({
collectionSlug: collectionConfig.slug,
desiredFilename: fsSafeName,
req,
staticPath,
})
}
fileData.filename = fsSafeName

View File

@@ -1,6 +1,6 @@
import sanitize from 'sanitize-filename'
import type { Payload } from '..'
import type { PayloadRequest } from '../express/types'
import docWithFilenameExists from './docWithFilenameExists'
import fileExists from './fileExists'
@@ -22,17 +22,29 @@ const incrementName = (name: string) => {
return `${incrementedName}.${extension}`
}
async function getSafeFileName(
payload: Payload,
collectionSlug: string,
staticPath: string,
desiredFilename: string,
): Promise<string> {
type Args = {
collectionSlug: string
desiredFilename: string
req: PayloadRequest
staticPath: string
}
async function getSafeFileName({
collectionSlug,
desiredFilename,
req,
staticPath,
}: Args): Promise<string> {
let modifiedFilename = desiredFilename
// eslint-disable-next-line no-await-in-loop
while (
(await docWithFilenameExists(payload, collectionSlug, staticPath, modifiedFilename)) ||
(await docWithFilenameExists({
collectionSlug,
filename: modifiedFilename,
path: staticPath,
req,
})) ||
(await fileExists(`${staticPath}/${modifiedFilename}`))
) {
modifiedFilename = incrementName(modifiedFilename)

View File

@@ -49,6 +49,7 @@ export async function getEntityPolicies<T extends Args>(args: T): Promise<Return
if (type === 'global') {
return req.payload.findGlobal({
overrideAccess: true,
req,
slug: entity.slug,
})
}

View File

@@ -59,12 +59,12 @@ export const saveVersion = async ({
},
}
if (collection) {
({ docs } = await payload.db.findVersions({
;({ docs } = await payload.db.findVersions({
...findVersionArgs,
collection: collection.slug
collection: collection.slug,
}))
} else {
({ docs } = await payload.db.findGlobalVersions({
;({ docs } = await payload.db.findGlobalVersions({
...findVersionArgs,
global: global.slug,
}))
@@ -72,7 +72,7 @@ export const saveVersion = async ({
const [latestVersion] = docs
// overwrite the latest version if it's set to autosave
if ((latestVersion)?.autosave === true) {
if (latestVersion?.autosave === true) {
createNewVersion = false
const data: Record<string, unknown> = {
@@ -87,14 +87,21 @@ export const saveVersion = async ({
versionData: data,
}
if (collection) {
result = await payload.db.updateVersion({ ...updateVersionArgs, collection: collection.slug })
result = await payload.db.updateVersion({
...updateVersionArgs,
collection: collection.slug,
})
} else {
result = await payload.db.updateGlobalVersion({ ...updateVersionArgs, global: global.slug })
result = await payload.db.updateGlobalVersion({
...updateVersionArgs,
global: global.slug,
})
}
}
}
if (createNewVersion) {
if (collection) {
result = await payload.db.createVersion({
autosave: Boolean(autosave),
collectionSlug: entityConfig.slug,
@@ -105,6 +112,19 @@ export const saveVersion = async ({
versionData,
})
}
if (global) {
result = await payload.db.createGlobalVersion({
autosave: Boolean(autosave),
createdAt: doc?.createdAt ? new Date(doc.createdAt).toISOString() : now,
globalSlug: entityConfig.slug,
parent: collection ? id : undefined,
req,
updatedAt: draft ? now : new Date(doc.updatedAt).toISOString(),
versionData,
})
}
}
} catch (err) {
let errorMessage: string
@@ -133,8 +153,6 @@ export const saveVersion = async ({
})
}
result = JSON.parse(JSON.stringify(result))
let createdVersion = result.version
createdVersion.createdAt = result.createdAt
createdVersion.updatedAt = result.updatedAt

View File

@@ -27,6 +27,9 @@ let globalGraphQLVersionID
const globalGraphQLOriginalTitle = 'updated global title'
const updatedTitle = 'Here is an updated post title in EN'
const formatGraphQLID = (id: number | string) =>
payload.db.defaultIDType === 'number' ? id : `"${id}"`
describe('Versions', () => {
beforeAll(async () => {
const config = await configPromise
@@ -601,8 +604,7 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
const data = response.createAutosavePost
collectionGraphQLPostID = payload.db.defaultIDType === 'number' ? data.id : `"${data.id}"`
collectionGraphQLPostID = data.id
})
describe('Create', () => {
it('should allow a new doc to be created with draft status', async () => {
@@ -634,7 +636,9 @@ describe('Versions', () => {
// modify the post to create a new version
// language=graphQL
const update = `mutation {
updateAutosavePost(id: ${collectionGraphQLPostID}, data: {title: "${updatedTitle2}"}) {
updateAutosavePost(id: ${formatGraphQLID(
collectionGraphQLPostID,
)}, data: {title: "${updatedTitle2}"}) {
title
updatedAt
createdAt
@@ -644,7 +648,9 @@ describe('Versions', () => {
// language=graphQL
const query = `query {
versionsAutosavePosts(where: { parent: { equals: ${collectionGraphQLPostID} } }) {
versionsAutosavePosts(where: { parent: { equals: ${formatGraphQLID(
collectionGraphQLPostID,
)} } }) {
docs {
id
}
@@ -653,15 +659,12 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
collectionGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosavePosts.docs[0].id
: `"${response.versionsAutosavePosts.docs[0].id}"`
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
})
it('should allow read of versions by version id', async () => {
const query = `query {
versionAutosavePost(id: ${collectionGraphQLVersionID}) {
versionAutosavePost(id: ${formatGraphQLID(collectionGraphQLVersionID)}) {
id
parent {
id
@@ -713,7 +716,9 @@ describe('Versions', () => {
// modify the post to create a new version
// language=graphQL
const update = `mutation {
updateAutosavePost(id: ${collectionGraphQLPostID}, data: {title: "${collectionGraphQLOriginalTitle}"}) {
updateAutosavePost(id: ${formatGraphQLID(
collectionGraphQLPostID,
)}, data: {title: "${collectionGraphQLOriginalTitle}"}) {
title
updatedAt
createdAt
@@ -723,7 +728,9 @@ describe('Versions', () => {
// language=graphQL
const query = `query {
versionsAutosavePosts(where: { parent: { equals: ${collectionGraphQLPostID} } }) {
versionsAutosavePosts(where: { parent: { equals: ${formatGraphQLID(
collectionGraphQLPostID,
)} } }) {
docs {
id
}
@@ -732,15 +739,14 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
collectionGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosavePosts.docs[0].id
: `"${response.versionsAutosavePosts.docs[0].id}"`
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
})
it('should allow a version to be restored', async () => {
// Update it
const update = `mutation {
updateAutosavePost(id: ${collectionGraphQLPostID}, data: {title: "${'Wrong title'}"}) {
updateAutosavePost(id: ${formatGraphQLID(
collectionGraphQLPostID,
)}, data: {title: "${'Wrong title'}"}) {
title
updatedAt
createdAt
@@ -750,7 +756,7 @@ describe('Versions', () => {
// restore a versionsPost
const restore = `mutation {
restoreVersionAutosavePost(id: ${collectionGraphQLVersionID}) {
restoreVersionAutosavePost(id: ${formatGraphQLID(collectionGraphQLVersionID)}) {
title
}
}`
@@ -758,7 +764,7 @@ describe('Versions', () => {
await graphQLClient.request(restore)
const query = `query {
AutosavePost(id: ${collectionGraphQLPostID}) {
AutosavePost(id: ${formatGraphQLID(collectionGraphQLPostID)}) {
title
}
}`
@@ -1002,16 +1008,13 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
globalGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosaveGlobal.docs[0].id
: `"${response.versionsAutosaveGlobal.docs[0].id}"`
globalGraphQLVersionID = response.versionsAutosaveGlobal.docs[0].id
})
describe('Read', () => {
it('should allow read of versions by version id', async () => {
// language=graphql
const query = `query {
versionAutosaveGlobal(id: ${globalGraphQLVersionID}) {
versionAutosaveGlobal(id: ${formatGraphQLID(globalGraphQLVersionID)}) {
id
version {
title
@@ -1054,7 +1057,7 @@ describe('Versions', () => {
it('should allow a version to be restored', async () => {
// language=graphql
const restore = `mutation {
restoreVersionAutosaveGlobal(id: ${globalGraphQLVersionID}) {
restoreVersionAutosaveGlobal(id: ${formatGraphQLID(globalGraphQLVersionID)}) {
title
}
}`