chore: progress to versions

This commit is contained in:
James
2023-09-23 07:50:28 -07:00
parent 7ea4fcde2c
commit ee0bddf85b
10 changed files with 156 additions and 69 deletions

View File

@@ -35,15 +35,17 @@ export const createVersion: CreateVersion = async function createVersion(
const table = this.tables[tableName]
const relationshipsTable = this.tables[`${tableName}_relationships`]
await db.execute(sql`
UPDATE ${table}
SET latest = false
FROM ${relationshipsTable}
WHERE ${table.id} = ${relationshipsTable.parent}
AND ${relationshipsTable.path} = ${'parent'}
AND ${relationshipsTable[`${collectionSlug}ID`]} = ${parent}
AND ${table.id} != ${result.id};
`)
if (collection.versions.drafts) {
await db.execute(sql`
UPDATE ${table}
SET latest = false
FROM ${relationshipsTable}
WHERE ${table.id} = ${relationshipsTable.parent}
AND ${relationshipsTable.path} = ${'parent'}
AND ${relationshipsTable[`${collectionSlug}ID`]} = ${parent}
AND ${table.id} != ${result.id};
`)
}
return result
}

View File

@@ -372,8 +372,8 @@ export const traverseFields = <T extends Record<string, unknown>>({
case 'date': {
let val = fieldData
if (fieldData instanceof Date) {
val = fieldData.toISOString()
if (typeof fieldData === 'string') {
val = new Date(fieldData).toISOString()
}
if (typeof locale === 'string') {

View File

@@ -104,11 +104,12 @@ function initCollectionsGraphQL(payload: Payload): void {
collection.graphQL.paginatedType = buildPaginatedListType(pluralName, collection.graphQL.type)
collection.graphQL.whereInputType = buildWhereInputType(
singularName,
whereInputFields,
singularName,
)
collection.graphQL.whereInputType = buildWhereInputType({
name: singularName,
fields: whereInputFields,
parentName: singularName,
payload,
})
if (config.auth && !config.auth.disableLocalStrategy) {
fields.push({
@@ -218,11 +219,12 @@ function initCollectionsGraphQL(payload: Payload): void {
}
if (config.versions) {
const versionIDType = payload.db.defaultIDType === 'text' ? GraphQLString : GraphQLInt
const versionCollectionFields: Field[] = [
...buildVersionCollectionFields(config),
{
name: 'id',
type: 'text',
type: payload.db.defaultIDType as 'text',
},
{
name: 'createdAt',
@@ -246,7 +248,7 @@ function initCollectionsGraphQL(payload: Payload): void {
payload.Query.fields[`version${formatName(singularName)}`] = {
args: {
id: { type: GraphQLString },
id: { type: versionIDType },
...(payload.config.localization
? {
fallbackLocale: { type: payload.types.fallbackLocaleInputType },
@@ -260,11 +262,12 @@ function initCollectionsGraphQL(payload: Payload): void {
payload.Query.fields[`versions${pluralName}`] = {
args: {
where: {
type: buildWhereInputType(
`versions${singularName}`,
versionCollectionFields,
`versions${singularName}`,
),
type: buildWhereInputType({
name: `versions${singularName}`,
fields: versionCollectionFields,
parentName: `versions${singularName}`,
payload,
}),
},
...(payload.config.localization
? {
@@ -284,7 +287,7 @@ function initCollectionsGraphQL(payload: Payload): void {
}
payload.Mutation.fields[`restoreVersion${formatName(singularName)}`] = {
args: {
id: { type: GraphQLString },
id: { type: versionIDType },
},
resolve: restoreVersionResolver(collection),
type: collection.graphQL.type,

View File

@@ -130,11 +130,12 @@ function initGlobalsGraphQL(payload: Payload): void {
payload.Query.fields[`versions${formattedName}`] = {
args: {
where: {
type: buildWhereInputType(
`versions${formattedName}`,
versionGlobalFields,
`versions${formattedName}`,
),
type: buildWhereInputType({
name: `versions${formattedName}`,
fields: versionGlobalFields,
parentName: `versions${formattedName}`,
payload,
}),
},
...(payload.config.localization
? {

View File

@@ -571,7 +571,12 @@ function buildObjectType({
const whereFields = payload.collections[relationTo].config.fields
upload.args.where = {
type: buildWhereInputType(uploadName, whereFields, uploadName),
type: buildWhereInputType({
name: uploadName,
fields: whereFields,
parentName: uploadName,
payload,
}),
}
return {

View File

@@ -2,6 +2,7 @@
/* eslint-disable no-use-before-define */
import { GraphQLInputObjectType, GraphQLList } from 'graphql'
import type { Payload } from '../..'
import type { Field, FieldAffectingData } from '../../fields/config/types'
import {
@@ -13,6 +14,13 @@ import formatName from '../utilities/formatName'
import fieldToSchemaMap from './fieldToWhereInputSchemaMap'
import { withOperators } from './withOperators'
type Args = {
fields: Field[]
name: string
parentName: string
payload: Payload
}
/** This does as the function name suggests. It builds a where GraphQL input type
* for all the fields which are passed to the function.
* Each field has different operators which may be valid for a where input type.
@@ -27,11 +35,12 @@ import { withOperators } from './withOperators'
* directly searchable. Instead, we need to build a chained pathname
* using dot notation so MongoDB can properly search nested paths.
*/
const buildWhereInputType = (
name: string,
fields: Field[],
parentName: string,
): GraphQLInputObjectType => {
const buildWhereInputType = ({
name,
fields,
parentName,
payload,
}: Args): GraphQLInputObjectType => {
// This is the function that builds nested paths for all
// field types with nested paths.
@@ -41,7 +50,10 @@ const buildWhereInputType = (
if (fieldAffectsData(field) && field.name === 'id') idField = field
if (!fieldIsPresentationalOnly(field) && !field.hidden) {
const getFieldSchema = fieldToSchemaMap(parentName)[field.type]
const getFieldSchema = fieldToSchemaMap({
parentName,
payload,
})[field.type]
if (getFieldSchema) {
const fieldSchema = getFieldSchema(field)

View File

@@ -1,5 +1,7 @@
import { GraphQLEnumType, GraphQLInputObjectType, GraphQLString } from 'graphql'
import GraphQLJSON from 'graphql-type-json'
import type { Payload } from '../..'
import type {
ArrayField,
CheckboxField,
@@ -22,14 +24,25 @@ import type {
UploadField,
} from '../../fields/config/types'
import { fieldAffectsData, fieldHasSubFields } from '../../fields/config/types'
import combineParentName from '../utilities/combineParentName'
import formatName from '../utilities/formatName'
import recursivelyBuildNestedPaths from './recursivelyBuildNestedPaths'
import { withOperators } from './withOperators'
const fieldToSchemaMap = (parentName: string, nestedFieldName?: string): any => ({
array: (field: ArrayField) => recursivelyBuildNestedPaths(parentName, nestedFieldName, field),
type Args = {
nestedFieldName?: string
parentName: string
payload: Payload
}
const fieldToSchemaMap = ({ nestedFieldName, parentName, payload }: Args): any => ({
array: (field: ArrayField) =>
recursivelyBuildNestedPaths({
field,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
checkbox: (field: CheckboxField) => ({
type: withOperators(field, parentName),
}),
@@ -37,14 +50,25 @@ const fieldToSchemaMap = (parentName: string, nestedFieldName?: string): any =>
type: withOperators(field, parentName),
}),
collapsible: (field: CollapsibleField) =>
recursivelyBuildNestedPaths(parentName, nestedFieldName, field),
recursivelyBuildNestedPaths({
field,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
date: (field: DateField) => ({
type: withOperators(field, parentName),
}),
email: (field: EmailField) => ({
type: withOperators(field, parentName),
}),
group: (field: GroupField) => recursivelyBuildNestedPaths(parentName, nestedFieldName, field),
group: (field: GroupField) =>
recursivelyBuildNestedPaths({
field,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
json: (field: JSONField) => ({
type: withOperators(field, parentName),
}),
@@ -77,7 +101,7 @@ const fieldToSchemaMap = (parentName: string, nestedFieldName?: string): any =>
),
}),
},
value: { type: GraphQLString },
value: { type: GraphQLJSON },
},
}),
}
@@ -90,11 +114,23 @@ const fieldToSchemaMap = (parentName: string, nestedFieldName?: string): any =>
richText: (field: RichTextField) => ({
type: withOperators(field, parentName),
}),
row: (field: RowField) => recursivelyBuildNestedPaths(parentName, nestedFieldName, field),
row: (field: RowField) =>
recursivelyBuildNestedPaths({
field,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
select: (field: SelectField) => ({
type: withOperators(field, parentName),
}),
tabs: (field: TabsField) => recursivelyBuildNestedPaths(parentName, nestedFieldName, field),
tabs: (field: TabsField) =>
recursivelyBuildNestedPaths({
field,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
text: (field: TextField) => ({
type: withOperators(field, parentName),
}),

View File

@@ -1,13 +1,17 @@
import type { Payload } from '../..'
import type { FieldWithSubFields, TabsField } from '../../fields/config/types'
import { fieldAffectsData, fieldIsPresentationalOnly } from '../../fields/config/types'
import fieldToSchemaMap from './fieldToWhereInputSchemaMap'
const recursivelyBuildNestedPaths = (
parentName: string,
nestedFieldName2: string,
field: FieldWithSubFields | TabsField,
) => {
type Args = {
field: FieldWithSubFields | TabsField
nestedFieldName2: string
parentName: string
payload: Payload
}
const recursivelyBuildNestedPaths = ({ field, nestedFieldName2, parentName, payload }: Args) => {
const fieldName = fieldAffectsData(field) ? field.name : undefined
const nestedFieldName = fieldName || nestedFieldName2
@@ -16,9 +20,14 @@ const recursivelyBuildNestedPaths = (
// otherwise, treat it as a row
return field.tabs.reduce((tabSchema, tab: any) => {
tabSchema.push(
...recursivelyBuildNestedPaths(parentName, nestedFieldName, {
...tab,
type: 'name' in tab ? 'group' : 'row',
...recursivelyBuildNestedPaths({
field: {
...tab,
type: 'name' in tab ? 'group' : 'row',
},
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
)
return tabSchema
@@ -30,14 +39,23 @@ const recursivelyBuildNestedPaths = (
if (!fieldAffectsData(nestedField)) {
return [
...nestedFields,
...recursivelyBuildNestedPaths(parentName, nestedFieldName, nestedField),
...recursivelyBuildNestedPaths({
field: nestedField,
nestedFieldName2: nestedFieldName,
parentName,
payload,
}),
]
}
const nestedPathName = fieldAffectsData(nestedField)
? `${nestedFieldName ? `${nestedFieldName}__` : ''}${nestedField.name}`
: undefined
const getFieldSchema = fieldToSchemaMap(parentName, nestedFieldName)[nestedField.type]
const getFieldSchema = fieldToSchemaMap({
nestedFieldName,
parentName,
payload,
})[nestedField.type]
if (getFieldSchema) {
const fieldSchema = getFieldSchema({

View File

@@ -178,7 +178,7 @@ const defaults: DefaultsType = {
operators: [
...[...operators.equality, ...operators.contains].map((operator) => ({
name: operator,
type: GraphQLString,
type: GraphQLJSON,
})),
],
},

View File

@@ -601,7 +601,8 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
const data = response.createAutosavePost
collectionGraphQLPostID = data.id
collectionGraphQLPostID = payload.db.defaultIDType === 'number' ? data.id : `"${data.id}"`
})
describe('Create', () => {
it('should allow a new doc to be created with draft status', async () => {
@@ -633,7 +634,7 @@ describe('Versions', () => {
// modify the post to create a new version
// language=graphQL
const update = `mutation {
updateAutosavePost(id: "${collectionGraphQLPostID}", data: {title: "${updatedTitle2}"}) {
updateAutosavePost(id: ${collectionGraphQLPostID}, data: {title: "${updatedTitle2}"}) {
title
updatedAt
createdAt
@@ -643,7 +644,7 @@ describe('Versions', () => {
// language=graphQL
const query = `query {
versionsAutosavePosts(where: { parent: { equals: "${collectionGraphQLPostID}" } }) {
versionsAutosavePosts(where: { parent: { equals: ${collectionGraphQLPostID} } }) {
docs {
id
}
@@ -652,12 +653,15 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
collectionGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosavePosts.docs[0].id
: `"${response.versionsAutosavePosts.docs[0].id}"`
})
it('should allow read of versions by version id', async () => {
const query = `query {
versionAutosavePost(id: "${collectionGraphQLVersionID}") {
versionAutosavePost(id: ${collectionGraphQLVersionID}) {
id
parent {
id
@@ -709,7 +713,7 @@ describe('Versions', () => {
// modify the post to create a new version
// language=graphQL
const update = `mutation {
updateAutosavePost(id: "${collectionGraphQLPostID}", data: {title: "${collectionGraphQLOriginalTitle}"}) {
updateAutosavePost(id: ${collectionGraphQLPostID}, data: {title: "${collectionGraphQLOriginalTitle}"}) {
title
updatedAt
createdAt
@@ -719,7 +723,7 @@ describe('Versions', () => {
// language=graphQL
const query = `query {
versionsAutosavePosts(where: { parent: { equals: "${collectionGraphQLPostID}" } }) {
versionsAutosavePosts(where: { parent: { equals: ${collectionGraphQLPostID} } }) {
docs {
id
}
@@ -728,12 +732,15 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
collectionGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosavePosts.docs[0].id
: `"${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: ${collectionGraphQLPostID}, data: {title: "${'Wrong title'}"}) {
title
updatedAt
createdAt
@@ -743,7 +750,7 @@ describe('Versions', () => {
// restore a versionsPost
const restore = `mutation {
restoreVersionAutosavePost(id: "${collectionGraphQLVersionID}") {
restoreVersionAutosavePost(id: ${collectionGraphQLVersionID}) {
title
}
}`
@@ -751,7 +758,7 @@ describe('Versions', () => {
await graphQLClient.request(restore)
const query = `query {
AutosavePost(id: "${collectionGraphQLPostID}") {
AutosavePost(id: ${collectionGraphQLPostID}) {
title
}
}`
@@ -995,13 +1002,16 @@ describe('Versions', () => {
const response = await graphQLClient.request(query)
globalGraphQLVersionID = response.versionsAutosaveGlobal.docs[0].id
globalGraphQLVersionID =
payload.db.defaultIDType === 'number'
? response.versionsAutosaveGlobal.docs[0].id
: `"${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: ${globalGraphQLVersionID}) {
id
version {
title
@@ -1044,7 +1054,7 @@ describe('Versions', () => {
it('should allow a version to be restored', async () => {
// language=graphql
const restore = `mutation {
restoreVersionAutosaveGlobal(id: "${globalGraphQLVersionID}") {
restoreVersionAutosaveGlobal(id: ${globalGraphQLVersionID}) {
title
}
}`