Skip to content

Instantly share code, notes, and snippets.

View lastmjs's full-sized avatar

Jordan Last lastmjs

View GitHub Profile
@lastmjs
lastmjs / js-tricks.js
Created February 25, 2017 02:10
Useful JavaScript utilities
// 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
import {GraphQLServer} from 'graphql-yoga';
import {makeExecutableSchema} from 'graphql-tools';
import {
Prisma,
Query,
Mutation
} from './generated/prisma';
import {readFileSync} from 'fs';
import {parse} from 'graphql';
import {
const preparedFieldResolvers = addFragmentToFieldResolvers(parse(readFileSync('./schema/datamodel.graphql').toString()), `{ id }`)
const generatedFragmentReplacements = extractFragmentReplacements(preparedFieldResolvers);
const PrismaDBConnection = new Prisma({
endpoint: 'http://127.0.0.1:4466/backend/dev', // 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
});
export function addFragmentToFieldResolvers(schemaAST, fragmentSelection) {
return schemaAST.definitions.reduce((result, schemaDefinition) => {
if (schemaDefinition.kind === 'ObjectTypeDefinition') {
return {
...result,
[schemaDefinition.name.value]: schemaDefinition.fields.reduce((result, fieldDefinition) => {
//TODO this includes check is naive and will break for some strings
if (fragmentSelection.includes(fieldDefinition.name.value)) {
return result;
}
export function prepareTopLevelResolvers(resolverObject: Query | Mutation) {
return Object.entries(resolverObject).reduce((result, entry) => {
const resolverName = entry[0];
const resolverFunction = entry[1];
return {
...result,
[resolverName]: async (parent, args, context, info) => {
return await resolverFunction(args, info);
}
};
const resolvers = {
Query: {
...preparedTopLevelQueryResolvers
},
Mutation: {
...preparedTopLevelMutationResolvers,
signup: signupResolver,
login: loginResolver
},
...preparedFieldResolvers
const directiveResolvers = {
userOwns: userOwnsDirectiveResolver,
authenticated: authenticatedDirectiveResolver,
private: privateDirectiveResolver
};
export async function userOwnsDirectiveResolver(next, source, args, context) {
if (source[args.field] === await getUserId(context)) {
return await next();
}
else {
throw new Error('Not authorized');
}
}
export async function authenticatedDirectiveResolver(next, source, args, context) {
if (getUserId(context)) {
return await next();
}
else {
throw new Error('Not authenticated');
}
}
export async function privateDirectiveResolver(next, source, args, context) {
throw new Error('Private');
}