Skip to content

Commit

Permalink
feat: Introduce SchemaBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Jun 22, 2017
1 parent 9b2c314 commit 2b6d5f3
Show file tree
Hide file tree
Showing 6 changed files with 3,453 additions and 1 deletion.
1 change: 1 addition & 0 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"lerna": "2.0.0-rc.5",
"npmClient": "yarn",
"packages": [
"packages/*"
],
Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"devDependencies": {
"lerna": "^2.0.0-rc.5"
"babel-eslint": "^7.2.3",
"eslint": "^4.0.0",
"eslint-config-prettier": "^2.1.1",
"eslint-plugin-jest": "^20.0.3",
"eslint-plugin-prettier": "^2.1.2",
"jest": "^20.0.4",
"lerna": "^2.0.0-rc.5",
"prettier": "^1.4.4"
},
"jest": {
"testRegex": "__tests__/.*\\.test\\.js$"
}
}
82 changes: 82 additions & 0 deletions packages/graphql-build/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const debug = require("debug")("graphql-builder");
const INDENT = " ";

class SchemaBuilder {
constructor() {
// this.context will be replaced by the 'context' hooks, do not store
// copies of it!
this.context = {};

// Because hooks can nest, this keeps track of how deep we are.
this.depth = -1;

this.hooks = {
// The context object is passed to all hooks, hook the 'context' event to
// extend this object:
context: [],

// Add 'query', 'mutation' or 'subscription' types in this hook:
schema: [],

// When creating a GraphQLObjectType we'll execute, in order, the
// following hooks:
// - 'objectType' to add any root-level attributes, e.g. add a description
// - 'objectType:fields' to add fields to this object type
// - 'objectType:field' to enhance an individual field
objectType: [],
"objectType:fields": [],
"objectType:field": [],
};
}

/*
* Every hook `fn` takes three arguments:
* - obj - the object currently being inspected
* - context - the global context object (which contains a number of utilities)
* - scope - information specific to the current invocation of the hook
*
* The function must either return a replacement object for `obj` or `obj` itself
*/
hook(hookName, fn) {
if (!this.hooks[hookName]) {
throw new Error(`Sorry, '${hookName}' is not a supported hook`);
}
this.hooks[hookName].push(fn);
}

applyHooks(hookName, oldObj, scope) {
const isContext = hookName === "context";
if (isContext) this.context = oldObj;

this.depth++;
debug(`${INDENT.repeat(this.depth)}[${hookName}]: Running...`);

const hooks = this.hooks[hookName];
if (!hooks) {
throw new Error(`Sorry, '${hookName}' is not a registered hook`);
}

let newObj = oldObj;
for (const hook of hooks) {
newObj = hook(newObj, this.context, scope);
if (!newObj) {
throw new Error(`Hook for '${hookName}' returned falsy value`);
}
if (isContext) {
this.context = newObj;
}
}

debug(`${INDENT.repeat(this.depth)}[${hookName}]: Complete`);
this.depth--;

return newObj;
}
}

const buildSchema = async (plugins, options) => {
const builder = new SchemaBuilder();
for (const plugin of plugins) {
await plugin(builder, options);
}
};
34 changes: 34 additions & 0 deletions packages/graphql-build/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "graphql-build",
"version": "0.0.0",
"description": "Build a GraphQL schema from plugins",
"main": "index.js",
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/benjie/graphql-build.git"
},
"keywords": [
"graphql",
"apollo",
"graphqljs",
"plugin",
"build",
"extension"
],
"author": "Benjie Gillam <benjie@jemjie.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/benjie/graphql-build/issues"
},
"homepage": "https://github.com/benjie/graphql-build#readme",
"dependencies": {
"dataloader": "^1.3.0",
"debug": ">=2",
"graphql": ">=0.9"
},
"engines": {
"node": ">=8",
"yarn": "^0.24.5"
}
}
27 changes: 27 additions & 0 deletions packages/graphql-build/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


dataloader@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.3.0.tgz#6fec5be4b30a712e4afd30b86b4334566b97673b"

debug@>=2:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"

graphql@>=0.9:
version "0.10.3"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.10.3.tgz#c313afd5518e673351bee18fb63e2a0e487407ab"
dependencies:
iterall "^1.1.0"

iterall@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.1.tgz#f7f0af11e9a04ec6426260f5019d9fcca4d50214"

ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"

0 comments on commit 2b6d5f3

Please sign in to comment.