Skip to content

Instantly share code, notes, and snippets.


Jordan Last lastmjs

View GitHub Profile
lastmjs / js-tricks.js
Created Feb 25, 2017
Useful JavaScript utilities
View js-tricks.js
// As far as is possible in all legal jurisdictions, I Jordan Last relinquish all rights to this code and place it in the public domain
// Execute asynchronous tasks in order
// Curry an arbitrary number of times
View fragments-for-directives.ts
const preparedFieldResolvers = addFragmentToFieldResolvers(parse(readFileSync('./schema/datamodel.graphql').toString()), `{ id }`)
const generatedFragmentReplacements = extractFragmentReplacements(preparedFieldResolvers);
const PrismaDBConnection = new Prisma({
endpoint: '', // the endpoint of the Prisma DB service
secret: 'mysecret123', // specified in database/prisma.yml //TODO obviously this should be controlled with environment variables
debug: true, // log all GraphQL queries & mutations
fragmentReplacements: generatedFragmentReplacements
View add-fragment-to-field-resolvers.ts
export function addFragmentToFieldResolvers(schemaAST, fragmentSelection) {
return schemaAST.definitions.reduce((result, schemaDefinition) => {
if (schemaDefinition.kind === 'ObjectTypeDefinition') {
return {
[]: schemaDefinition.fields.reduce((result, fieldDefinition) => {
//TODO this includes check is naive and will break for some strings
if (fragmentSelection.includes( {
return result;
View prepare-top-level-resolvers.ts
export function prepareTopLevelResolvers(resolverObject: Query | Mutation) {
return Object.entries(resolverObject).reduce((result, entry) => {
const resolverName = entry[0];
const resolverFunction = entry[1];
return {
[resolverName]: async (parent, args, context, info) => {
return await resolverFunction(args, info);
View resolvers.ts
const resolvers = {
Query: {
Mutation: {
signup: signupResolver,
login: loginResolver
View directive-resolvers.ts
const directiveResolvers = {
userOwns: userOwnsDirectiveResolver,
authenticated: authenticatedDirectiveResolver,
private: privateDirectiveResolver
View authenticated-directive-resolver.ts
export async function authenticatedDirectiveResolver(next, source, args, context) {
if (getUserId(context)) {
return await next();
else {
throw new Error('Not authenticated');
View private-directive-resolver.ts
export async function privateDirectiveResolver(next, source, args, context) {
throw new Error('Private');
View datamodel.graphql
# All types defined here will be fed through the Prisma generation process
# Essentially, all of these types become database tables
type User {
id: ID! @unique
createdAt: DateTime! @private
updatedAt: DateTime! @private
email: String! @unique @userOwns(field: "id")
password: String! @private
View directives.graphql
directive @userOwns(field: String) on FIELD | FIELD_DEFINITION
directive @authenticated on FIELD | FIELD_DEFINITION
directive @private on FIELD | FIELD_DEFINITION
You can’t perform that action at this time.