Skip to content

Instantly share code, notes, and snippets.

Jordan Last lastmjs

Block or report user

Report or block lastmjs

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@lastmjs
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: '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
});
View add-fragment-to-field-resolvers.ts
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;
}
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 {
...result,
[resolverName]: async (parent, args, context, info) => {
return await resolverFunction(args, info);
}
};
View resolvers.ts
const resolvers = {
Query: {
...preparedTopLevelQueryResolvers
},
Mutation: {
...preparedTopLevelMutationResolvers,
signup: signupResolver,
login: loginResolver
},
...preparedFieldResolvers
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.