Skip to content
This repository has been archived by the owner on Jun 22, 2023. It is now read-only.

Commit

Permalink
feat(project): automatically set created and modified properties
Browse files Browse the repository at this point in the history
Fixes #112
  • Loading branch information
ChristiaanScheermeijer committed Mar 11, 2021
1 parent 021ea58 commit 3029fb1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import walkSync from 'walk-sync'
import { resolvers } from './resolvers'
import { authenticationFieldTransformer } from './transformers/authenticationFieldTransformer'
import { subscriptionFieldTransformer } from './transformers/subscriptionFieldTransformer'
import { createdUpdatedFieldTransformer } from './transformers/createdUpdatedFieldTransformer'

/*
* Determine type definitions from which to auto generate queries and mutations
Expand Down Expand Up @@ -46,6 +47,7 @@ export const schema = transformSchema(
}),
[
subscriptionFieldTransformer,
authenticationFieldTransformer
authenticationFieldTransformer,
createdUpdatedFieldTransformer,
]
)
63 changes: 63 additions & 0 deletions src/transformers/createdUpdatedFieldTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { TransformRootFields } from 'graphql-tools'
import { buildPropertyValue, parseFieldName } from '../utils/schema'
import { buildArgument, buildName } from 'neo4j-graphql-js/dist/augment/ast'
import { Kind } from 'graphql/language/kinds'

export const createdUpdatedFieldTransformer = new TransformRootFields((operation, fieldName, field) => {
// Only needed for mutations
if (operation !== 'Mutation') {
return undefined
}

const { action } = parseFieldName(fieldName)

if (action !== 'Create' && action !== 'Update' && action !== 'Merge') {
return undefined
}

const next = field.resolve

field.resolve = (object, params, context, info) => {
info.fieldNodes = info.fieldNodes.map(fieldNode => {
const createdIndex = fieldNode.arguments.findIndex(argument => argument.name.value === 'created')
const modifiedIndex = fieldNode.arguments.findIndex(argument => argument.name.value === 'modified')

// remove given created and modified arguments
if (createdIndex !== -1) {
fieldNode.arguments.splice(createdIndex, 1)
}

if (modifiedIndex !== -1) {
fieldNode.arguments.splice(modifiedIndex, 1)
}

const date = new Date()

const value = {
kind: Kind.OBJECT,
fields: [
buildPropertyValue('year', Kind.INT, date.getUTCFullYear()),
buildPropertyValue('month', Kind.INT, date.getUTCMonth()),
buildPropertyValue('day', Kind.INT, date.getUTCDate()),
buildPropertyValue('hour', Kind.INT, date.getUTCHours()),
buildPropertyValue('minute', Kind.INT, date.getUTCMinutes()),
buildPropertyValue('second', Kind.INT, date.getUTCSeconds()),
buildPropertyValue('millisecond', Kind.INT, date.getUTCMilliseconds()),
buildPropertyValue('timezone', Kind.STRING, 'z')
]
}

if (action === 'Create') {
fieldNode.arguments.push(buildArgument({ name: buildName({ name: 'created' }), value }))
}

if (action === 'Create' || action === 'Update' || action === 'Update') {
fieldNode.arguments.push(buildArgument({ name: buildName({ name: 'modified' }), value }))
}

return fieldNode
})

return next(object, params, context, info)
}
})
20 changes: 20 additions & 0 deletions src/utils/schema.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Kind } from 'graphql/language/kinds'
import { buildName } from 'neo4j-graphql-js/dist/augment/ast'

/**
* Parse the given field name into an action and type
* @param {string} fieldName
Expand All @@ -23,3 +26,20 @@ export const generateScope = (mutation, fieldName) => {

return `${mutation}:${type}:${action}`
}

/**
* Build an ObjectField AST node
* @param name
* @param kind
* @param value
* @return {{kind: "ObjectField", name: *, value: {kind, block: boolean, value}}}
*/
export const buildPropertyValue = (name, kind, value) => ({
kind: Kind.OBJECT_FIELD,
name: buildName({ name: name }),
value: {
kind: kind,
value: value,
block: false
}
})

0 comments on commit 3029fb1

Please sign in to comment.