UNPKG

53.8 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width,initial-scale=1">
6 <title>LatticeFactory.js - Documentation</title>
7
8 <script src="scripts/prettify/prettify.js"></script>
9 <script src="scripts/prettify/lang-css.js"></script>
10 <!--[if lt IE 9]>
11 <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
12 <![endif]-->
13 <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
14 <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
15 <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
16</head>
17<body>
18
19<input type="checkbox" id="nav-trigger" class="nav-trigger" />
20<label for="nav-trigger" class="navicon-button x">
21 <div class="navicon"></div>
22</label>
23
24<label for="nav-trigger" class="overlay"></label>
25
26<nav>
27 <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AwaitingPromiseError.html">AwaitingPromiseError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError.html#%25E2%258C%25BE%25E2%25A0%2580asyncFn">⌾⠀asyncFn</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError.html#%25E2%258C%25BE%25E2%25A0%2580setPromise">⌾⠀setPromise</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AwaitingPromiseError_exports.AwaitingPromiseError.html">AwaitingPromiseError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError_exports.AwaitingPromiseError.html#setPromise">setPromise</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Deferred_exports.Deferred.html">Deferred</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DirectTypeAdd.html">DirectTypeAdd</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="FunctionExecutionError_FunctionExecutionError.html">FunctionExecutionError</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLBase.html">GQLBase</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.apiDocs">apiDocs</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getMergedRoot">⌾⠀getMergedRoot</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getProp">⌾⠀getProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getResolver">⌾⠀getResolver</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580IDLFilePath">⌾⠀IDLFilePath</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580MUTATORS">⌾⠀MUTATORS</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580RESOLVERS">⌾⠀RESOLVERS</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580setupModel">⌾⠀setupModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580handler">⬇︎⠀handler</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580SCHEMA">⬇︎⠀SCHEMA</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580applyAutoProps">⌾⠀applyAutoProps</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580callProp">⌾⠀callProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580extendModel">⌾⠀extendModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getModel">⌾⠀getModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getProp">⌾⠀getProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getResolver">⌾⠀getResolver</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580setModel">⌾⠀setModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%25AC%2586%25EF%25B8%258E%25E2%25A0%2580requestData">⬆︎⠀requestData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580requestData">⬇︎⠀requestData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#~deleteProperty">deleteProperty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#~set">set</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLBase.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLEnum.html">GQLEnum</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#..get">.get</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#..set">.set</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.valueFor">valueFor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580enums">⬇︎⠀enums</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580name">⬇︎⠀name</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580value">⬇︎⠀value</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580values">⬇︎⠀values</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#GenerateEnumsProxyHandler">GenerateEnumsProxyHandler</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html">GQLExpressMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#.clearCache">clearCache</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#.%25E2%258C%25BE%25E2%25A0%2580generateSchemaSDL">⌾⠀generateSchemaSDL</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#astMiddleware">astMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#schemaMiddleware">schemaMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%258C%25BE%25E2%25A0%2580customMiddleware">⌾⠀customMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580middleware">⬇︎⠀middleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580middlewareWithoutGraphiQL">⬇︎⠀middlewareWithoutGraphiQL</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580schema">⬇︎⠀schema</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLExpressMiddleware.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLInterface.html">GQLInterface</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLInterface.html#.%25E2%258C%25BE%25E2%25A0%2580resolveType">⌾⠀resolveType</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLScalar.html">GQLScalar</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.parseLiteral">parseLiteral</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.parseValue">parseValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.serialize">serialize</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IDLFileHandler.html">IDLFileHandler</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getFile">⌾⠀getFile</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getSchema">⌾⠀getSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getSyntaxTree">⌾⠀getSyntaxTree</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IDLFileHandler.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ModuleParser.html">ModuleParser</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#.%25E2%258C%25BE%25E2%25A0%2580arrayToPattern">⌾⠀arrayToPattern</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#.%25E2%258C%25BE%25E2%25A0%2580checkForPackageExtensions">⌾⠀checkForPackageExtensions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580findGQLBaseClasses">⌾⠀findGQLBaseClasses</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580importClass">⌾⠀importClass</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580parse">⌾⠀parse</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580parseSync">⌾⠀parseSync</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258C%25BE%25E2%25A0%2580walk">⌾⠀walk</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258C%25BE%25E2%25A0%2580walkSync">⌾⠀walkSync</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258E%2586%25E2%25A0%2580constructor">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ModuleParser.exports.ModuleParser.html">exports.ModuleParser</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="SchemaUtils.html">SchemaUtils</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580createMergedRoot">⌾⠀createMergedRoot</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectComments">⌾⠀injectComments</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectEnums">⌾⠀injectEnums</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectInterfaceResolvers">⌾⠀injectInterfaceResolvers</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectScalars">⌾⠀injectScalars</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="SyntaxTree.html">SyntaxTree</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyDocument">⌾⠀EmptyDocument</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyMutation">⌾⠀EmptyMutation</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyQuery">⌾⠀EmptyQuery</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findDefinition">⌾⠀findDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findField">⌾⠀findField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findInASTArrayByNameValue">⌾⠀findInASTArrayByNameValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580from">⌾⠀from</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580fromAST">⌾⠀fromAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580fromSchema">⌾⠀fromSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258E%2586%25E2%25A0%2580constructor">⎆⠀constructor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580appendDefinitions">⌾⠀appendDefinitions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580consumeDefinition">⌾⠀consumeDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580find">⌾⠀find</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580findEnumDefinition">⌾⠀findEnumDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580setAST">⌾⠀setAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580toString">⌾⠀toString</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580updateAST">⌾⠀updateAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%25AC%2586%25EF%25B8%258E%25E2%25A0%2580ast">⬆︎⠀ast</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580ast">⬇︎⠀ast</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="utils.Deferred.html">Deferred</a></span></li><li class="nav-heading">Namespaces</li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="decorators.html">decorators</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#.%25E2%258C%25BE%25E2%25A0%2580extractBits">⌾⠀extractBits</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580AdjacentSchema">.🏷⠀AdjacentSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580FileSchema">.🏷⠀FileSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Getters">.🏷⠀Getters</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Properties">.🏷⠀Properties</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Schema">.🏷⠀Schema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Setters">.🏷⠀Setters</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#~decorate">decorate</a></span></li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="GQLBaseEnv.html">GQLBaseEnv</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBaseEnv.html#~notDefined">notDefined</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#applyTags">applyTags</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#AsyncFunctionExecutionError">AsyncFunctionExecutionError</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_API_DOCS">CHECK_API_DOCS</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_RESOLVERS">CHECK_RESOLVERS</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_SCHEMA">CHECK_SCHEMA</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECKLIST">CHECKLIST</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#FunctionExecutionError">FunctionExecutionError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getChecklist">getChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#hasChecklist">hasChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#newChecklist">newChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setChecklist">setChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#types">types</a></span></li>
28</nav>
29
30<div id="main">
31
32 <h1 class="page-title">LatticeFactory.js</h1>
33
34
35
36
37
38
39
40 <section>
41 <article>
42 <pre class="prettyprint source linenums"><code>// @flow
43
44import { GQLBase, META_KEY } from './GQLBase'
45import { GQLEnum } from './GQLEnum'
46import { GQLInterface } from './GQLInterface'
47import { GQLScalar } from './GQLScalar'
48// import { GQLUnion } from './GQLUnion'
49import { SyntaxTree } from './SyntaxTree'
50import { customDedent } from 'ne-tag-fns'
51import { typeOf, extendsFrom } from 'ne-types'
52import { inspect } from 'util'
53import { resolver, mutator, subscriptor } from './decorators/Resolvers'
54import { Properties } from './decorators/ModelProperties'
55import { LatticeLogs as LL } from './utils'
56
57const _i = (...args) => inspect(...args, {colors: true, depth: 3})
58
59
60/**
61 * The CHECKLIST Symbol is used as a storage key in the metadata staging
62 * area for each of the GQLBase extended classes. In the LatticeFactory
63 * it is used to determine where in the flow of construction the class
64 * currently is.
65 *
66 * @type {Symbol}
67 */
68export const CHECKLIST = Symbol.for('checklist')
69
70/**
71 * The CHECK_SCHEMA Symbol is part of the CHECKLIST for a constructed
72 * GQLBase extended class. It denotes that the class has had its SCHEMA
73 * getter defined.
74 *
75 * @type {Symbol}
76 */
77export const CHECK_SCHEMA = Symbol.for('checklist-schema')
78
79/**
80 * The CHECK_RESOLVERS Symbol is part of the CHECKLIST for a constructed
81 * GQLBase extended class. It denotes that the class has had its instance
82 * field resolvers as well as its static Query, Mutation and Subscription
83 * resolvers injected and defined.
84 *
85 * @type {Symbol}
86 */
87export const CHECK_RESOLVERS = Symbol.for('checklist-resolvers')
88
89/**
90 * The CHECK_API_DOCS Symbol is part of the CHECKLIST for a constructed
91 * GQLBase extended class. It denotes that the class has had its api docs
92 * defined, processed and setup on the class in a way that it will be
93 * picked up in the build lifecycle.
94 *
95 * @type {Symbol}
96 */
97export const CHECK_API_DOCS = Symbol.for('checklist-api-docs')
98
99/**
100 * Peeks into the metadata storage area of a given GQLBase extended
101 * class and fetches the factory checklist if one exists.
102 *
103 * @param {Function} Class a reference to the GQLBase class to peek in
104 * @return {Object} an object setup with at least three booleans keyed by
105 * the constants CHECK_SCHEMA, CHECK_RESOLVERS, and CHECK_API_DOCS or null
106 * if none exists
107 */
108export function getChecklist(Class: Function) {
109 return (Class &amp;&amp; Class[META_KEY] &amp;&amp; Class[META_KEY][CHECKLIST]) || null
110}
111
112/**
113 * Obtains the checklist from the supplied GQLBase extended class. If the
114 * class has a checklist, its checklist item is set to true or the boolean
115 * value specified.
116 *
117 * @param {Function} Class a reference to the GQLBase class to set
118 * @param {Symbol} item one of CHECK_SCHEMA, CHECK_RESOLVERS, or
119 * CHECK_API_DOCS
120 * @param {Boolean} value the value for the checklist item to set
121 */
122export function setChecklist(
123 Class: Function,
124 item: Symbol,
125 value: boolean = true
126) {
127 let checklist = getChecklist(Class)
128
129 if (checklist) {
130 // $FlowFixMe
131 checklist[item] = value
132 }
133}
134
135/**
136 * This function, when invoked with only a class will return true if the
137 * Class has a defined checklist. If one ore more CHECKLIST symbols are
138 * passed, the function will only return true if all the supplied symbols
139 * are set to truthy values.
140 *
141 * @param {Function} Class a reference to the GQLBase class to set
142 * @param {Array&lt;Symbol>} items any of CHECK_SCHEMA, CHECK_RESOLVERS, or
143 * CHECK_API_DOCS
144 * @return {Boolean} true if the checklist and/or all items are true and
145 * present.
146 */
147export function hasChecklist(Class: Function, ...items: Array&lt;Symbol>) {
148 let checklist = getChecklist(Class)
149
150 if (checklist &amp;&amp; items.length) {
151 for (let item of items) {
152 if (!checklist[item]) {
153 return false
154 }
155 }
156
157 return true
158 }
159
160 return checklist
161}
162
163/**
164 * Injects and creates a new CHECKLIST object on the supplied GQLBase
165 * extended class. All items are installed and set to false.
166 *
167 * @param {Function} Class a reference to the GQLBase class to set
168 */
169export function newChecklist(Class: Function) {
170 if (Class) {
171 // $FlowFixMe
172 Class[META_KEY][CHECKLIST] = {
173 [CHECK_SCHEMA]: false,
174 [CHECK_RESOLVERS]: false,
175 [CHECK_API_DOCS]: false,
176
177 get keys() {
178 return [
179 CHECK_SCHEMA, CHECK_RESOLVERS, CHECK_API_DOCS
180 ]
181 },
182
183 get complete() {
184 return this.keys.reduce((p,c,i,a) => {
185 if (!p || !this[c]) { return false }
186 }, true)
187 }
188 }
189 }
190 else {
191 throw new Error(customDedent({dropLowest:true})`
192 Cannot create new checklist metadata on a non-existent class
193 `)
194 }
195}
196
197export class ValidationResults {
198 errors: Array&lt;Error>
199
200 constructor(errors: Array&lt;Error> = []) {
201 this.errors = errors
202 }
203
204 get valid(): boolean { return this.errors.length === 0 }
205
206 // $FlowFixMe
207 get [Symbol.toStringTag](): string { return this.constructor.name }
208
209 // $FlowFixMe
210 static get [Symbol.toStringTag](): string { return this.name }
211}
212
213export class LatticeFactory {
214
215 /**
216 * Walks through a supplied template object and collects errors with its
217 * format before bubbling up an exception if any part of it fails to
218 * pass muster. The exception can be prevented from throwing if hide is set
219 * to true
220 *
221 * @param {Object} template an object to be parsed for construction via the
222 * Lattice Factory
223 * @param {boolean} hide if true, an invalid template will NOT throw errors
224 * @return {ValidationResults} a `ValidationResults` object containing the
225 * collected errors and a `valid` that is dynamically calculated.
226 */
227 static validateTemplate(
228 template: Object,
229 hide: boolean = false
230 ): ValidationResults {
231 let results = new ValidationResults()
232 let indent = (string: string, count: number = 4, space: string = ' ') => (
233 string
234 .split('\n')
235 .map(s => s.trim().replace(/(^)/gm, `$1${space.repeat(count)}`))
236 .join('\n')
237 )
238
239 if (typeof template.name === 'undefined') {
240 results.errors.push(new Error(customDedent({dropLowest:true})`
241 The \`template.name\` field must exist or the creation for the Lattice
242 factory class generation to succeed.
243
244 Please read the documentation for more information on the format of
245 a LatticeFactory template.
246 `))
247 }
248
249 if (!extendsFrom(template.name, String)) {
250 results.errors.push(new Error(customDedent({dropLowest:true})`
251 The \`template.name\` field must be a string.
252
253 Please read the documentation for more information on the format of
254 a LatticeFactory template.
255 `))
256 }
257
258 if (typeof template.schema === 'undefined') {
259 results.errors.push(new Error(customDedent({dropLowest:true})`
260 The \`template.schema\` field must exist or the creation for the
261 Lattice factory class generation to succeed.
262
263 Please read the documentation for more information on the format of
264 a LatticeFactory template.
265 `))
266 }
267
268 if (!extendsFrom(template.schema, String)) {
269 results.errors.push(new Error(customDedent({dropLowest:true})`
270 The \`template.schema\` field must be a string of GraphQL SDL/IDL
271
272 Please read the documentation for more information on the format of
273 a LatticeFactory template.
274 `))
275 }
276
277 if (
278 !extendsFrom(template.resolvers, Object) // Supports 95% of objects
279 || typeof template.resolvers !== 'object' // Supports Object.create(null)
280 ) {
281 results.errors.push(new Error(customDedent({dropLowest:true})`\x1b[91;1m
282 The \`template.resolvers\` field must be an Object containing the
283 resolver functions. Query, Mutation and Subscription resolvers will
284 take the following signature. Additionally, the keys for these special
285 resolvers must be Query, Mutation or Subscription; respectively
286 \x1b[37;22m
287 Query: { [resolver]: (requestData, resolverParameters) => {} }
288 Mutation: { [resolver]: (requestData, resolverParameters) => {} }
289 Subscription: { [resolver]: (requestData, resolverParameters) => {} }
290
291 where:
292 \`requestData\` is an object with { req, res, gql|next } depending
293 on the graphql server implementation (FB Reference, Apollo, etc)
294 \`resovlerParameters\` is an object with keys matching those
295 parameters defined in the SCHEMA for the resolver in question.
296 \x1b[91;1m
297 Field resolvers should be found under the key name of the type
298 or interface in question and must correspond to the following signature
299 \x1b[37;22m
300 [Type]: { [resolver]: (resolverParameters) => {} }
301
302 where:
303 \`Type\` is the name of the GQL type defined in the schema
304 \`resovlerParameters\` is an object with keys matching those
305 parameters defined in the SCHEMA for the resolver in question.
306
307 * it is worth noting that the field resolvers are not static and
308 can access the \`requestData\` object via \`this.requestData\`
309 \x1b[91;1m
310 Please read the documentation for more information on the format of
311 a LatticeFactory template.\x1b[0m
312 `))
313 }
314
315 if (typeof template.docs === 'undefined') {
316 results.errors.push(new Error(customDedent({dropLowest:true})`
317 The \`template.docs\` field must exist for the creation of the
318 Lattice factory class generation to succeed.
319
320 Please read the documentation for more information on the format of
321 a LatticeFactory template.
322 `))
323 }
324
325 if (
326 !extendsFrom(template.docs, Object) // Supports 95% of objects
327 || typeof template.docs !== 'object' // Supports Object.create(null)
328 ) {
329 let dr = '\x1b[31m', br = '\x1b[91m'
330 let b1 = '\x1b[1m', b0 = '\x1b[22m'
331 let bb = '\x1b[90m'
332 let dg = '\x1b[37m', bg = '\x1b[97m'
333 let a0 = '\x1b[0m'
334 let gr = '\x1b[32m', bgr = '\x1b[92m'
335
336 results.errors.push(new Error(customDedent({dropLowest:true})`\x1b[1;91m
337 The \`template.docs\` field must be an object containing keys and
338 value pairs matching the types, enums, unions and interfaces defined
339 in your schema.
340
341 The special Symbol object TYPE can be used to reference the docs for
342 the named or keyed field describing the documentation to be processed
343 Comments for the \`Query\`, \`Mutation\`, and \`Subscription\` [TYPE]
344 entries will replace any previous one that comes before it. Typically
345 this field is best left undescribed since there will ever only be
346 one of each at most.
347
348 \x1b[22;31mExamples should look something like this:\x1b[22;37m
349 import { TYPE, joinLines } from 'graphql-lattice'
350
351 export default {
352 ${bb}/* other fields */${dg}
353
354 ${b1}schema:${b0} joinLines${gr}\`
355 type Person { id: ID name: String }
356 type Query { findPerson(id: ID): Person }
357 type Mutation { setPersonName(id: ID, name: String): Person }
358 \`${dg},
359
360 ${b1}docs:${b0} {
361 ${b1}Person:${b0} {
362 [TYPE]: ${gr}'A contrived person type'${dg},
363 id: ${gr}'A unique identifier for a person'${dg},
364 name: ${gr}'A string denoting the name of a person'${dg}
365 },
366 ${b1}Query:${b0} {
367 findPerson: ${gr}'A query taking an ID, returns a Person'${dg},
368 },
369 ${b1}Mutation:${b0} {
370 setPersonName: joinLines${gr}\`
371 A mutation that sets the name of the user identified by an
372 ID to the new name value supplied
373 \`${dg}
374 }
375 }
376 }
377 \x1b[22;31m
378 Note the usage of \`Person\`, \`Query\` and \`Mutation\` explicitly
379 as keys to the supplied \`docs\` object.\x1b[0m
380 `))
381 }
382
383 if (!results.valid) {
384 let errorStrings = []
385
386 for (let error of results.errors) {
387 let { message, stack } = error
388
389 stack = stack
390 .trim()
391 .split('\n')
392 .splice(message.split('\n').length)
393 .map(s => s.trim())
394 .join('\n')
395 message = message.replace(/(Error:\s)/, '$1\n').trim()
396
397 errorStrings.push(
398 `\x1b[31;1m${message}\x1b[0m\n` + indent(stack)
399 )
400 }
401
402 let error = new Error(customDedent({dropLowest:true})`
403 OOPS!
404
405 An error occurred validating your factory template. The object
406 in question is as follows:
407
408 @template
409
410 The individual errors that occurred are:
411 \n@errors`
412 .replace(/@template/, indent(_i(template)))
413 .replace(/@errors/, errorStrings.join('\n\n'))
414 )
415
416 error.stack = error.message
417 error.message = ''
418
419 if (!hide) throw error
420 }
421
422 return results
423 }
424
425 /**
426 * The starting point of a LatticeFactory object -> class creation. The name
427 * of the class and baseClass to use are provided and are created from there.
428 * At this point, the generated class is still incomplete. It must complete
429 * the entire checklist before being deemed valid.
430 *
431 * @param {string} name name of the class to create
432 * @param {Function} baseClass the Lattice class your new class should extend;
433 * while this can be anything, it should be GQLBase, GQLInterface, GQLEnum or
434 * GQLUnion. This defaults to GQLBase should nothing be supplied
435 * @return {Function} actually this returns the generated class
436 */
437 static generateClass(name: string, baseClass: Function = GQLBase) {
438 if (!name) {
439 throw new Error('LatticeFactory.generateClass needs a name!!')
440 }
441
442 // Alright ladies and gentlemen, hold onto your hats; we're entering the
443 // meta zone!!! The way the following works is to make sure that our
444 // passed in base class `baseClass` is actually in scope as the name of
445 // the value it represents. We use the `new Function()` syntax to do that
446 // but we do it via eval since we don't know the name of the function
447 // at the time we write the code
448 //
449 // So given a class name of "Car" and baseName equalling GQLBase, the Class
450 // instance, fn would look something like the results of calling this
451 //
452 // let fn = new Function(
453 // "GQLBase",
454 // "class Car extends GQLBase {}; return Car;"
455 // )
456 //
457 // Which in turn sets fn to something that would be the same as
458 //
459 // function fn(GQLBase) { class Car extends GQLBase {}; return Car }
460 //
461 // Which means that when we invoke fn(baseClass), which is fn(GQLBase),
462 // we get the results we intend; even if GQLBase is not necessarily in
463 // the scope of the function at the time of call. Neat. Scary. OMG Thanks
464 // for code comments. You're welcome future me.
465 let fn = eval(`(new Function(
466 "${baseClass.name}",
467 "class ${name} extends ${baseClass.name} {}; return ${name};"
468 ))`);
469
470 let Class = fn(baseClass)
471
472 this.brandClass(Class)
473 newChecklist(Class)
474
475 return Class;
476 }
477
478 /**
479 * Injects the SCHEMA property into the newly defined class. The supplied
480 * `schema` string becomes what the new class returns when `.SCHEMA` is
481 * gotten.
482 *
483 * @param {Function} Class this will throw an error if the class is not one
484 * generated by the LatticeFactory or if the class itself is null or undefined
485 * @param {string} schema the string that the new class should return
486 * @return {Function} returns the modified Class with the `CHECK_SCHEMA`
487 * portion ticked off internally.
488 */
489 static injectSchema(Class: Function, schema: string) {
490 if (!Class || !hasChecklist(Class)) {
491 throw new Error(customDedent({dropLowest:true})`
492 Either the supplied schema string is invalid
493 SCHEMA: \`
494 ${schema}
495 \`
496
497 Or your supplied class ${(Class &amp;&amp; Class.name) || 'undefined'} is
498 non-existent. Please check your code and try the LatticeFactory
499 again.
500 `)
501 }
502
503 // $FlowFixMe
504 Object.defineProperty(Class, 'SCHEMA', {
505 get() { return schema }
506 })
507
508 setChecklist(Class, CHECK_SCHEMA)
509
510 return Class
511 }
512
513 /**
514 * Injects the resolvers into appropriate areas. Resolvers keyed by `Query`,
515 * `Mutation`, or `Subscription` will be placed into the appropriate area
516 * in `Class[META_KEY]` which acts as a staging area originally designed for
517 * use with the @resolver, @mutator and @subscriptor decorators. These will
518 * be bound in a typical fashion as is done with the decorators making the
519 * first parameter becoming the requestData of the object instance and the
520 * second being the object containing the parameters for the resolver as
521 * passed in by GraphQL. Subsequent parameters will be supplied as is the
522 * fashion of the system you're using; Facebook's reference implementation or
523 * Apollo or something else.
524 *
525 * Resolvers keyed by type name are considered to be field resolvers and
526 * have a different signature. They can be properties of the key, in
527 * which case they will simply be installed as getters. Or they can be
528 * functions; synchronous or asynchronous. Function field resolvers are
529 * instance methods and can make use of `this.getModel()` or
530 * `this.requestData` internally.
531 *
532 * @param {Function} Class the class, generated by generateClass() lest an
533 * error be thrown, to which to add the resolvers from a template
534 * @param {Object} resolverObj an object containing the resolvers as dictated
535 * by the new format.
536 * @return {Function} returns the modified Class with the `CHECK_RESOLVERS`
537 * portion ticked off internally.
538 */
539 static injectResolvers(Class: Function, resolvers: Object): Function {
540 if (!hasChecklist(Class, CHECK_SCHEMA)) {
541 throw new Error(customDedent({dropLowest:true})`
542 \`injectResolvers\` cannot be called on a class without a SCHEMA.
543 Please verify your progress in the process and try again.
544 `)
545 }
546
547 let tree = SyntaxTree.from(Class.SCHEMA)
548 let outline = tree ? tree.outline : {}
549
550 if (Class.name in outline &amp;&amp; Class.name in resolvers) {
551 let fields = Object.keys(outline[Class.name])
552
553 for (let fieldResolver of fields) {
554 if (!fieldResolver in resolvers[Class.name]) {
555 LL.warn(customDedent({dropLowest: true})`
556 ${fieldResolver} not supplied in resolvers for ${Class.name}
557 `)
558 continue;
559 }
560
561 let prop = resolvers[Class.name][fieldResolver]
562
563 if (prop &amp;&amp; typeof prop === 'function') {
564 LL.info('Injecting [fn] %s', fieldResolver)
565 Object.defineProperty(Class.prototype, fieldResolver, {
566 value: prop
567 })
568 }
569 else {
570 LL.info('Injecting [prop] %s', fieldResolver)
571 Properties(fieldResolver)(Class, ['factory-props'])
572 }
573 }
574 }
575
576 for (let [type: string, decorator: Function] of [
577 ['Query', resolver],
578 ['Mutation', mutator],
579 ['Subscription', subscriptor]
580 ]) {
581 let keys = Object.keys(outline[type] || {})
582
583 // $FlowFixMe
584 if (!type in outline || !keys.length) { continue; }
585
586 for (let fnName of keys) {
587 let fn = resolvers[fnName]
588 decorator(Class, fnName, {value: fn})
589 LL.info('Adding %s resolver [%s]', type, fnName)
590 }
591 }
592
593 setChecklist(Class, CHECK_RESOLVERS)
594
595 return Class
596 }
597
598 static injectDocs(Class: Function, docs: Object): Function {
599 if (!hasChecklist(Class, CHECK_SCHEMA, CHECK_RESOLVERS)) {
600 throw new Error(customDedent({dropLowest:true})`
601 \`injectDocs\` cannot be called on a class without a SCHEMA or
602 RESOLVERS defined. Please verify your progress in the process and try
603 again.
604 `)
605 }
606
607 let copyProp = (
608 o: mixed,
609 prop: string | Symbol,
610 to: mixed,
611 as: ?(string | Symbol)
612 ): mixed => {
613 // $FlowFixMe
614 let prototype = o.prototype || Object.getPrototypeOf(o)
615 let descriptor = Object.getOwnPropertyDescriptor(prototype, prop)
616
617 if (!as) {
618 as = prop
619 }
620
621 if (descriptor) {
622 Object.defineProperty(to, as, descriptor)
623 }
624 else {
625 // $FlowFixMe
626 to[as] = o[prop]
627 }
628 }
629
630 // Create an object our future `static apiDocs()` method of our factory
631 // generated class will return
632 let result = {}
633
634 // Setup the constants we will need in this conversion
635 const { TYPE } = this;
636 const {
637 DOC_CLASS, DOC_FIELDS, DOC_QUERY, DOC_MUTATION, DOC_SUBSCRIPTION,
638 DOC_QUERIES, DOC_MUTATIONS, DOC_SUBSCRIPTIONS
639 } = GQLBase
640
641 // This part might get a little meta, so I have provided comments. You are
642 // welcome future me. I hope it helps. This gnarly block should cover all
643 // the descriptions for Query, Mutation, Subscription and the Class we
644 // are creating. Other superfluous
645 for (let [Type, TopLevelConstant, FieldConstants] of [
646 ['Query', DOC_QUERY, DOC_QUERIES],
647 ['Mutation', DOC_MUTATION, DOC_MUTATIONS],
648 ['Subscription', DOC_SUBSCRIPTION, DOC_SUBSCRIPTIONS],
649 [Class.name, DOC_CLASS, DOC_FIELDS]
650 ]) {
651 // One of 'Query', 'Mutation', or 'Subscription'
652 if (docs[Type]) {
653 // If a top level description is present (i.e. Query, Mutation or
654 // Subscription description)
655 if (docs[Type][TYPE]) {
656 copyProp(docs[Type], TYPE, result, TopLevelConstant)
657 }
658
659 // Fetch the properties from the supplied docs object; TYPE Symbols
660 // do not show up in a call to entries which is why it is handled above
661 // $FlowFixMe
662 let entries = Object.entries(docs[Type])
663
664 // If we have entries to document, create an object to hold those
665 // values; i.e. if we have `{ Query: { getPeople: 'desc' } }`, we need
666 // to make sure we have `{ [DOC_QUERIES]: { getPeople: 'desc' } }` in
667 // our result. The object holding getPeople in the end there is defined
668 // below when we have something to copy.
669 if (entries.length) {
670 result[FieldConstants] = {}
671 }
672
673 // For each name value pair defined above, copy its descriptor or base
674 // value if a descriptor isn't available
675 for (let [prop, value] of entries) {
676 copyProp(docs[Type], prop, result[FieldConstants])
677 }
678 }
679 }
680
681 Object.defineProperty(Class, 'apiDocs', {
682 value: function() { return result }
683 })
684
685 setChecklist(Class, CHECK_API_DOCS)
686
687 return Class
688 }
689
690 static build(template: Object): Function {
691 let validationResults = this.validateTemplate(template)
692 let Class = this.generateClass(template.name, template.type || GQLBase)
693
694 if (!Class) {
695 throw new Error(customDedent({dropLowest: true})`
696 LatticeFactory was unable to build your Class from the name and types
697 supplied in your template. You provided the following template. Please
698 look it over and correct any errors before trying again.
699
700 \x1b[1mTemplate\x1b[0m
701 ${_i(template)}
702 `)
703 }
704
705 this.injectSchema(Class, template.schema)
706 this.injectResolvers(Class, template.resolvers || {})
707 this.injectDocs(Class, template.docs || {})
708
709 // Need to fix how auto-props work; for now create one instance...
710 new Class({})
711
712 if (!hasChecklist(Class, CHECK_SCHEMA, CHECK_RESOLVERS, CHECK_API_DOCS)) {
713 let _schema = hasChecklist(Class, CHECK_SCHEMA) ? '✅' : '❌'
714 let _resolvers = hasChecklist(Class, CHECK_RESOLVERS) ? '✅' : '❌'
715 let _apiDocs = hasChecklist(Class, CHECK_API_DOCS) ? '✅' : '❌'
716
717 throw new Error(customDedent({dropLowest: true})`
718 Something went wrong in the process of building the class called
719 ${Class &amp;&amp; Class.name || template &amp;&amp; template.name || 'Unknown!'},
720 please check the supplied template for errors.
721
722 [ ${_schema} ] Has a SCHEMA defined
723 [ ${_resolvers} ] Has defined RESOLVERS matching the SCHEMA
724 [ ${_apiDocs} ] Has defined API Docs matching the SCHEMA
725
726 \x1b[1mTemplate\x1b[0m
727 ${_i(template)}
728
729 \x1b[1mClass\x1b[0m
730 ${_i(Class)}
731 `)
732 }
733
734 return Class
735 }
736
737 /**
738 * A static helper method to consistently tag, or brand, classes with a
739 * symbol that denotes they were created using the LatticeFactory process.
740 * This is done by setting a `Symbol` on the root of the class or in the
741 * `[META_KEY]` object for classes extending `GQLBase`.
742 *
743 * @method ⌾⠀brandClass
744 * @memberof LatticeFactory
745 * @static
746 *
747 * @param {Function} Class the class to brand with the `FACTORY_CLASS` symbol
748 * @return {Function} returns the Class value passed in
749 */
750 static brandClass(Class: ?Function): ?Function {
751 if (Class) {
752 if (extendsFrom(Class, GQLBase)) {
753 Class[META_KEY][this.FACTORY_CLASS] = true
754 }
755 else {
756 Class[this.FACTORY_CLASS] = true
757 }
758 }
759
760 return Class
761 }
762
763 /**
764 * A static helper to check and see if the supplied class or function was
765 * branded with the `brandClass()` function. This amounts to storing the
766 * boolean true under the property `Class[LatticeFactory.FACTORY_CLASS]` or
767 * `Class[META_KEY][LatticeFacatory.FACTORY_CLASS]` for `GQLBase` extended
768 * classes.
769 *
770 * @method ⌾⠀isFactoryClass
771 * @memberof LatticeFactory
772 * @static
773 *
774 * @param {Function} Class the class to check for `FACTORY_CLASS` branding
775 * @return {boolean} true if the brand exists, false otherwise
776 */
777 static isFactoryClass(Class: Function): boolean {
778 if (Class) {
779 return (extendsFrom(Class, GQLBase)
780 ? !!Class[META_KEY][this.FACTORY_CLASS]
781 : !!Class[this.FACTORY_CLASS]
782 )
783 }
784
785 return false
786 }
787
788 /**
789 * A static helper method to consistently remove any previous tag or brand
790 * applied with `brandClass`, this is done by removing a previously set
791 * `Symbol` on the root of the class or in the `[META_KEY]` object for
792 * classes extending `GQLBase`.
793 *
794 * @method ⌾⠀removeClassBrand
795 * @memberof LatticeFactory
796 * @static
797 *
798 * @param {Function} Class the class to brand with the `FACTORY_CLASS` symbol
799 * @return {Function} returns the Class value passed in
800 */
801 static removeClassBrand(Class: Function): Function {
802 if (Class) {
803 if (extendsFrom(Class, GQLBase)) {
804 delete Class[META_KEY][this.FACTORY_CLASS]
805 }
806 else {
807 delete Class[this.FACTORY_CLASS]
808 }
809 }
810
811 return Class
812 }
813
814 /**
815 * A constant that reports that this class is `'[object LatticeFactory]'`
816 * rather than `'[object Object]'` when introspected with tools such as
817 * `Object.prototype.toString.apply(class)`.
818 *
819 * @memberof LatticeFactory
820 * @type {Symbol}
821 * @static
822 */
823 // $FlowFixMe
824 static get [Symbol.toStringTag]() { return this.name }
825
826 /**
827 * A constant exported as part of LatticeFactory that can be used for
828 * defining documentation for the type itself.
829 *
830 * @memberof LatticeFactory
831 * @type {Symbol}
832 * @static
833 */
834 static get TYPE(): Symbol { return Symbol.for('API Docs Type Constant') }
835
836 /**
837 * A constant exported as part of LatticeFactory that can be used for
838 * identifying classes that were generated with LatticeFactory.
839 *
840 * @memberof LatticeFactory
841 * @type {Symbol}
842 * @static
843 */
844 static get FACTORY_CLASS(): Symbol { return Symbol.for('Factory Class') }
845}
846
847export const isFactoryClass = LatticeFactory.isFactoryClass
848
849// TESTING REPL
850/**
851var { LatticeFactory, getChecklist, hasChecklist, CHECKLIST, CHECK_SCHEMA, CHECK_RESOLVERS } = require('./dist/LatticeFactory'); var { GQLBase, META_KEY, joinLines, SyntaxTree, typeOf } = require('./dist/lattice'); var gql = joinLines, LF = LatticeFactory, TYPE = LF.TYPE;
852var PersonDef = { name: 'Person', schema: gql` enum StatType { PHYSICAL, MENTAL } type Person { name: String stats(type:StatType): Stat } type Query { findPerson(id: ID): Person } `, resolvers: { Query: { findPerson({req, res, next}, {id}) { console.log('find person') } }, Person: { stats({type}) { let { req, res, next} = this.requestData } } }, docs: { StatType: { [TYPE]: `A type of statistic associated with people`, PHYSICAL: `Physical attributes`, MENTAL: `Mental attributes` }, Person: { [TYPE]: `Represents a person`, personId: `Unique id of the person in question`, name: `The name of the person`, stats: `Allows you to query the stats of a person based on type` }, Query: { [TYPE]: 'Top level query desc.', findPerson: `Searches the system for the specified user` } } };
853var Person = LF.build(PersonDef), p = new Person({name: 'Brielle'})
854Person.getProp('stats',true,{requestData:{req:1,res:2,next:3}})
855var Broke = LF.build({name: 'Broke', schema: gql`type Broke {name: String}`, resolvers:{}, docs:{}})
856var t = LF.validateTemplate({name: '', type: GQLBase, resolvers: {}, docs: {}, schema: ''});
857*/
858</code></pre>
859 </article>
860 </section>
861
862
863
864
865</div>
866
867<br class="clear">
868
869<footer>
870 Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Jun 08 2018 19:28:39 GMT-0700 (PDT) using the Minami theme.
871</footer>
872
873<script>prettyPrint();</script>
874<script src="scripts/linenumber.js"></script>
875</body>
876</html>