Last active
May 1, 2020 21:15
-
-
Save ptpaterson/e5f68bb22561246fb664257231af1d71 to your computer and use it in GitHub Desktop.
Convert a function to a FaunaDB Let expression
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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