Skip to content

Instantly share code, notes, and snippets.

@ptpaterson
Last active May 1, 2020 21:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptpaterson/e5f68bb22561246fb664257231af1d71 to your computer and use it in GitHub Desktop.
Save ptpaterson/e5f68bb22561246fb664257231af1d71 to your computer and use it in GitHub Desktop.
Convert a function to a FaunaDB Let expression
const { query: q } = require('faunadb')
// fn-annotate
// https://www.npmjs.com/package/fn-annotate
const annotate = require('fn-annotate')
// converts a function into a faunaDB Let expression, but allows it to be used,
// as a regular function. This allows functions to be composed in JS land and
// turn out correctly in Fauna land.
const functionToLet = (fn) => (...args) => {
const params = annotate(fn)
const arity = params.length
const bindings = args.reduce(
(result, arg, index) =>
index < arity
? [
...result,
{
[params[index]]: arg,
},
]
: result,
[]
)
return q.Let(
bindings,
fn.apply(
null,
params.map((param) => q.Var(param))
)
)
}
// EXAMPLE
// *****************************************************************************
// some contrived library functions
const addUniqueField = functionToLet((collectionRef, fieldName) =>
q.CreateIndex({
name: 'needsABetterName',
source: collectionRef,
unique: true,
terms: [{ field: ['data', name] }],
})
)
const refOrAbort = functionToLet((maybeRef) =>
q.If(q.Exists(maybeRef), maybeRef, q.Abort('does not exist'))
)
// *****************************************************************************
// contrived app code
const collectionRef = refOrAbort(q.Collection('User'))
const query = addUniqueField(collectionRef, 'email')
// *****************************************************************************
// equivalent query
const equivQuery = q.Let(
{
collectionRef: q.Let(
{
maybeRef: q.Collection('User')
},
q.If(
q.Exists(q.Var('maybeRef')),
q.Var('maybeRef'),
q.Abort('does not exist')
)
),
},
q.CreateIndex({
name: 'needsABetterName',
source: q.Var('collectionRef'),
unique: true,
terms: [{ field: ['data', 'email'] }],
})
)
module.exports = functionToLet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment