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 index.ts
import {GraphQLServer} from 'graphql-yoga';
import {makeExecutableSchema} from 'graphql-tools';
import {
} from './generated/prisma';
import {readFileSync} from 'fs';
import {parse} from 'graphql';
import {
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 user-owns-directive-resolver.ts
export async function userOwnsDirectiveResolver(next, source, args, context) {
if (source[args.field] === await getUserId(context)) {
return await next();
else {
throw new Error('Not authorized');
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');
You can’t perform that action at this time.