UNPKG

@nyteshade/lattice-legacy

Version:

OO Underpinnings for ease of GraphQL Implementation

872 lines (789 loc) 65.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>GQLBase.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <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> </nav> <div id="main"> <h1 class="page-title">GQLBase.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** @namespace GQLBaseEnv */ // @flow import Path from 'path' import fs from 'fs' import { Deferred, joinLines } from './utils' import { typeOf } from 'ne-types' import { SyntaxTree } from './SyntaxTree' import { Properties } from './decorators/ModelProperties' import { GraphQLObjectType, GraphQLEnumType } from 'graphql' import { IDLFileHandler } from './IDLFileHandler' import { merge } from 'lodash' import { LatticeLogs as ll } from './utils' import { dedent } from 'ne-tag-fns' import AsyncFunctionExecutionError from './errors/AsyncFunctionExecutionError' import FunctionExecutionError from './errors/FunctionExecutionError' import AwaitingPromiseError from './errors/AwaitingPromiseError' import EventEmitter from 'events' /* Internal implementation to detect the existence of proxies. When present * additional functionality is enabled. Proxies are native in Node >= 6 */ const hasProxy = typeof global.Proxy !== 'undefined'; /* Internal Symbol referring to real accessor to GQLBase model object */ const _MODEL_KEY = Symbol.for('data-model-contents-value'); /* Internal Symbol referring to the static object containing a proxy handler */ const _PROXY_HANDLER = Symbol.for('internal-base-proxy-handler') /** * Simple function to check if a supplied key matches a string of your * choosing and that string is not a defined property on the instance * passed to the check. * * @method GQLBaseEnv~notDefined * @memberof GQLBaseEnv * @since 2.5.0 * * @param {string} keyToTest a String denoting the property you wish to test * @param {mixed} keySupplied a value, coerced `toString()`, to compare to * `keyToTest` * @param {mixed} instance an object instance to check `hasOwnProperty` on for * the `keyToTest` supplied. * @return {Boolean} true if the property matches the supplied key and that * property is not an ownedProperty of the instance supplied. */ export function notDefined( keyToTest: string, keySupplied: Object | string, instance: Object ) { return ( new RegExp("^" + keyToTest + "$").test(keySupplied.toString()) &amp;&amp; !instance.hasOwnProperty(keyToTest) ); } /** * A `Symbol` used as a key to store the backing model data. Designed as a * way to separate model data and GraphQL property accessors into logical bits. * * @type {Symbol} * @memberof GQLBaseEnv * @const */ export const MODEL_KEY = Symbol.for('data-model-contents-key'); /** * A `Symbol` used as a key to store the request data for an instance of the * GQLBase object in question. * * @type {Symbol} * @const * @inner * @memberof GQLBaseEnv */ export const REQ_DATA_KEY = Symbol.for('request-data-object-key'); /** * A nameless Symbol for use as a key to the internal decorator storage * * @type {Symbol} * @const * @inner * @memberof GQLBaseEnv */ export const META_KEY = Symbol(); /** * A Symbol used to identify calls to @Properties for properties generated * automatically upon instance creation. * * @type {Symbol} * @const * @inner * @memberOf GQLBaseEnv */ export const AUTO_PROPS = Symbol.for('auto-props') /** * A Symbol used to identify calls to @Getters for properties generated * via decorator. These are stored in &lt;class>[META_KEY][GETTERS] * * @type {Symbol} * @const * @inner * @memberOf GQLBaseEnv */ export const GETTERS = Symbol.for('getters') /** * A Symbol used to identify calls to @Setters for properties generated * via decorator. These are stored in &lt;class>[META_KEY][SETTERS] * * @type {Symbol} * @const * @inner * @memberOf GQLBaseEnv */ export const SETTERS = Symbol.for('setters') /** * A Symbol used to identify calls to @Properties for properties generated * via decorator. These are stored in &lt;class>[META_KEY][PROPS] * * @type {Symbol} * @const * @inner * @memberOf GQLBaseEnv */ export const PROPS = Symbol.for('props') /** * All GraphQL Type objects used in this system are assumed to have extended * from this class. An instance of this class can be used to wrap an existing * structure if you have one. * * @class GQLBase */ export class GQLBase extends EventEmitter { fileHandler: ?IDLFileHandler; /** * Request data is passed to this object when constructed. Typically these * objects, and their children, are instantiated by its own static MUTATORS * and RESOLVERS. They should contain request specific state if any is to * be shared. * * These can be considered request specific controllers for the object in * question. The base class takes a single object which should contain all * the HTTP/S request data and the graphQLParams is provided as the object * { query, variables, operationName, raw }. * * When used with express-graphql, the requestData object has the format * { req, res, gql } where * • req is an Express 4.x request object * • res is an Express 4.x response object * • gql is the graphQLParams object in the format of * { query, variables, operationName, raw } * See https://github.com/graphql/express-graphql for more info * * @memberof GQLBase * @method ⎆⠀constructor * @constructor * * @param {mixed} modelData this, typically an object, although anything * really is supported, represents the model data for our GraphQL object * instance. * @param {Object} requestData see description above */ constructor( modelData: Object = {}, requestData: ?Object = null, options: Object = { autoProps: true } ) { super(); const Class = this.constructor; const tree = SyntaxTree.from(Class.SCHEMA); const outline = tree &amp;&amp; tree.outline || null; if (!outline) { throw new FunctionExecutionError( new Error(dedent` The SDL is unparsable. Please check your SCHEMA and make sure it is valid GraphQL SDL/IDL. Your SCHEMA is defined as: ${this.SCHEMA} `) ) } if (outline &amp;&amp; !(Class.name in outline)) { throw new FunctionExecutionError( new Error(dedent` The class name "${Class.name}" does not match any of the types, enums, scalars, unions or interfaces defined in the SCHEMA for this class (${Object.keys(outline)}). \x1b[1mIn most clases this is because your class name and SCHEMA type do not match.\x1b[0m `) ) } GQLBase.setupModel(this); this.setModel(modelData); this.requestData = requestData || {}; this.fileHandler = new IDLFileHandler(this.constructor); if (options &amp;&amp; !!options.autoProps !== false) { this.applyAutoProps() } // @ComputedType return hasProxy ? new Proxy(this, GQLBase[_PROXY_HANDLER]) : this; } /** * Since reading the Schema for a given GraphQL Lattice type or * interface is simple enough, we should be able to automatically * apply one to one GraphQL:Model properties. * * @instance * @method ⌾⠀applyAutoProps * @memberof GQLBase */ applyAutoProps() { if (!this.constructor.SCHEMA || !this.constructor.SCHEMA.length) { ll.warn(joinLines` There is no SCHEMA for ${this.constructor.name}!! This will likely end in an error. Proceed with caution. Skipping \`applyAutoProps\` `) return } // Individual property getters do not need to be auto-created for enum // types. Potentially do some checks for Interfaces and Unions as well if (this.constructor.GQL_TYPE === GraphQLEnumType) { return } let Class = this.constructor let tree = SyntaxTree.from(Class.SCHEMA) let outline = tree ? tree.outline : {} let props = [] // $FlowFixMe for (let propName of Object.keys(outline[Class.name])) { // $FlowFixMe let desc = Object.getOwnPropertyDescriptor(Class.prototype, propName) let hasCustomImpl = !!( // We have a descriptor for the property name desc &amp;&amp; ( // We have a getter function defined typeof desc.get !== 'undefined' || // ...or we have a function, async or not, defined typeof desc.value === 'function' ) ) // Only create auto-props for non custom implementations if (!hasCustomImpl) { props.push(propName) } } if (props.length) { ll.info(`Creating auto-props for [${Class.name}]: `, props) try { Properties(...props)(Class, [AUTO_PROPS]) } catch(error) { let parsed = /Cannot redefine property: (\w+)/.exec(error.message) if (parsed) { ll.warn(`Skipping auto-prop '${Class.name}.${parsed[1]}'`) } else { ll.error(`Failed to apply auto-properties\nReason: `) ll.error(error); } } } } /** * Getter for the internally stored model data. The contents of this * object are abstracted away behind a `Symbol` key to prevent collision * between the underlying model and any GraphQL Object Definition properties. * * @instance * @memberof GQLBase * @method ⌾⠀getModel * @since 2.5 * * @param {Object} value any object you wish to use as a data store */ getModel() { // @ComputedType return this[MODEL_KEY]; } /** * Setter for the internally stored model data. The contents of this * object are abstracted away behind a `Symbol` key to prevent collision * between the underlying model and any GraphQL Object Definition properties. * * @instance * @memberof GQLBase * @method ⌾⠀setModel * @since 2.5 * * @param {Object} value any object you wish to use as a data store */ setModel(value: Object): GQLBase { // @ComputedType this[MODEL_KEY] = value; return this; } /** * Uses `_.merge()` to modify the internal backing data store for the * object instance. This is a shortcut for * `_.merge()(instance[MODEL_KEY], ...extensions)` * * @instance * @memberof GQLBase * @method ⌾⠀extendModel * @since 2.5 * * @param {mixed} extensions n-number of valid `_.merge()` parameters * @return {GQLBase} this is returned */ extendModel(...extensions: Array&lt;mixed>): GQLBase { // $FlowFixMe merge(this[MODEL_KEY], ...extensions); return this; } /** * A getter that retrieves the inner request data object. When used with * GQLExpressMiddleware, this is an object matching {req, res, gql}. * * @instance * @memberof GQLBase * @method ⬇︎⠀requestData * * @return {Object} an object, usually matching { req, res, gql } */ get requestData(): Object | null { // @ComputedType return this[REQ_DATA_KEY]; } /** * A setter that assigns a value to the inner request data object. When * used with GQLExpressMiddleware, this is an object matching {req, res, gql}. * * @instance * @memberof GQLBase * @method ⬆︎⠀requestData * * @param {Object} value an object, usually matching { req, res, gql } */ set requestData(value: Object): void { // @ComputedType this[REQ_DATA_KEY] = value; } /** * Returns the `constructor` name. If invoked as the context, or `this`, * object of the `toString` method of `Object`'s `prototype`, the resulting * value will be `[object MyClass]`, given an instance of `MyClass` * * @method ⌾⠀[Symbol.toStringTag] * @memberof ModuleParser * * @return {string} the name of the class this is an instance of * @ComputedType */ get [Symbol.toStringTag]() { return this.constructor.name } /** * Properties defined for GraphQL types in Lattice can be defined as * a getter, a function or an async function. In the case of standard * functions, if they return a promise they will be handled as though * they were async * * Given the variety of things a GraphQL type can actually be, obtaining * its value can annoying. This method tends to lessen that boilerplate. * Errors raised will be thrown. * * @instance * @memberof GQLBase * @method ⌾⠀getProp * * @param {string|Symbol} propName the name of the property in question * @param {boolean} bindGetters true, by default, if the `get` or * `initializer` descriptor values should be bound to the current instance * or an object of the programmers choice before returning * @param {mixed} bindTo the `this` object to use for binding when * `bindGetters` is set to true. * @return {mixed} the value of the `propName` as a Function or something * else when the requested property name exists * * @throws {Error} errors raised in awaiting results will be thrown */ getProp(propName: string, bindGetters: boolean = true, bindTo: mixed) { // $FlowFixMe let proto = Object.getPrototypeOf(this) let descriptor = Object.getOwnPropertyDescriptor(proto, propName) let result if (!descriptor) { return null; } if (descriptor) { if (descriptor.initializer || descriptor.get) { let what = descriptor.initializer || descriptor.get if (bindGetters) { result = what.bind(bindTo || this) } else { result = what } } else if (descriptor.value) { result = descriptor.value } } return result } /** * Properties defined for GraphQL types in Lattice can be defined as * a getter, a function or an async function. In the case of standard * functions, if they return a promise they will be handled as though * they were async. In addition to fetching the property, or field * resolver, its resulting function or getter will be invoked. * * Given the variety of things a GraphQL type can actually be, obtaining * its value can annoying. This method tends to lessen that boilerplate. * Errors raised will be thrown. * * @instance * @memberof GQLBase * @method ⌾⠀callProp * * @param {string} propName the name of the property in question * @param {Array&lt;mixed>} args the arguments array that will be passed * to `.apply()` should the property evaluate to a `function` * @return {mixed} the return value of any resulting function or * value returned by a getter; wrapped in a promise as all async * functions do. * * @throws {Error} errors raised in awaiting results will be thrown */ async callProp(propName: string, ...args: Array&lt;mixed>) { // $FlowFixMe let prop = this.getProp(propName, ...args); let result if (prop &amp;&amp; typeOf(prop) === 'AsyncFunction') { try { result = await prop.apply(this, args); } catch (error) { throw new AsyncFunctionExecutionError(error, prop, args, result) } } else if (prop &amp;&amp; typeOf(prop) === Function.name) { try { result = prop.apply(this, args) } catch (error) { throw new FunctionExecutionError(error, prop, args, result) } if (typeOf(result) === Promise.name) { try { result = await result } catch (error) { throw new AwaitingPromiseError(error).setPromise(result) } } } return result } /** * A pass-thru method to the static function of the same name. The * difference being that if `requestData` is not specified, the * `requestData` object from this instance will be used to build the * resolvers in question. * * @instance * @method ⌾⠀getResolver * @memberof GQLBase * * @param {string} resolverName the name of the resolver as a string * @param {Object} requestData the requestData used to build the * resolver methods from which to choose * @return {Function} returns either a `function` representing the * resolver requested or null if there wasn't one to be found */ async getResolver(resolverName: string, requestData: Object) { return await this.constructor.getResolver( resolverName, requestData || this.requestData ) } /** * Resolvers are created in a number of different ways. OOP design * dictates that instances of a created class will handle field * resolvers, but query, mutation and subscription resolvers are * typically what creates these instances. * * Since a resolver can be created using `@mutator/@subscriptor/@resolver` * or via method on a object returned from `RESOLVERS()`, `MUTATORS()` or * `SUBSCRIPTIONS()`, there should be an easy to use way to fetch a * resolver by name; if for nothing else, code reuse. * * Pass the name of the resolver to the function and optionally pass a * requestData object. The `getMergedRoot()` method will build an object * containing all the root resolvers for the type, bound to the supplied * `requestData` object. It is from this object that `resolverName` will * be used to fetch the function in question. If one exists, it will be * returned, ready for use. Otherwise, null will be your answer. * * * @static * @method ⌾⠀getResolver * @memberof GQLBase * * @param {string} resolverName the name of the resolver as a string * @param {Object} requestData the requestData used to build the * resolver methods from which to choose * @return {Function} returns either a `function` representing the * resolver requested or null if there wasn't one to be found */ static async getResolver(resolverName: string, requestData: Object) { const reqData = requestData || null const rootObj = await this.getMergedRoot(reqData) return rootObj[resolverName] || null } /** * The static version of getProp reads into the prototype to find the field * that is desired. If the field is either a getter or a initializer (see * class properties descriptors), then the option to bind that to either the * prototype object or one of your choosing is available. * * @memberof GQLBase * @method ⌾⠀getProp * @static * * @param {string|Symbol} propName a string or Symbol denoting the name of * the property or field you desire * @param {boolean} bindGetters true if a resulting `getter` or `initializer` * should be bound to the prototype or other object * @param {mixed} bindTo the object to which to bind the `getter` or * `initializer` functions to if other than the class prototype. * @return {mixed} a `Function` or other mixed value making up the property * name requested */ static getProp( propName: string, bindGetters: boolean = false, bindTo: mixed ) { let descriptor = Object.getOwnPropertyDescriptor(this.prototype, propName) if (descriptor) { if (descriptor.get || descriptor.initializer) { let what = descriptor.initializer || descriptor.get if (bindGetters) { bindTo = bindTo || this.prototype return what.bind(bindTo) } else { return what } } else { return descriptor.value } } else { return null } } /** * Until such time as the reference implementation of Facebook's GraphQL * SDL AST parser supports comments, or until we take advantage of Apollo's * AST parser, this is how comments will be applied to a built schema. * * Several constants are defined on the GQLBase object itself, and thereby * all its subclasses. They pertain to how to define description fields * for various parts of your GQL implementation. * * ``` * // To define a description on the top level class * [this.DOC_CLASS]: string * * // To define a description on a field (getter, function or async function) * [this.DOC_FIELDS]: { * fieldName: string * } * * // To define a description on a query, mutation or subscription field * [this.DOC_QUERIES || this.DOC_MUTATORS || this.DOC_SUBSCRIPTIONS]: { * fieldName: string * } * ``` * * To make writing code easier, the `joinLines()` template function is * available so your source code can look nice and neat and your descriptions * won't get annoying line breaks and spaces as part of that process. * * @static * @memberof GQLBase * @method apiDocs * * @return {Object} an object with various keys and values denoting * description fields that should be applied to the final schema object */ static apiDocs(): Object { return { [this.DOC_CLASS]: joinLines` GQLBase class implementation. GQLBase is the root class used in graphql-lattice to describe a GraphQLObjectType. If you are reading this, the person using lattice failed to provide documentation for their type. :) `, [this.DOC_QUERY]: joinLines` ## Welcome to GraphQL Lattice **Query** You will want to define a \`DOC_QUERY\` apiDoc comment with something more meaningful to your particular Schema here. `, [this.DOC_MUTATION]: joinLines` ## Welcome to GraphQL Lattice **Mutation** You will want to define a \`DOC_MUTATION\` apiDoc comment with something more meaningful to your particular Schema here. `, [this.DOC_SUBSCRIPTION]: joinLines` ## Welcome to GraphQL Lattice **Subscription** You will want to define a \`DOC_SUBSCRIPTION\` apiDoc comment with something more meaningful to your particular Schema here. `, [this.DOC_FIELDS]: { // fieldName: `fieldDescription`, }, [this.DOC_QUERIES]: { // queryName: `queryDescription`, }, [this.DOC_MUTATORS]: { // mutatorName: `mutatorDescription` }, [this.DOC_SUBSCRIPTIONS]: { // subscriptionName: `subscriptionDescription` } } } /** * Defined in a base class, this getter should return either a String * detailing the full IDL schema of a GraphQL handler or one of two * types of Symbols. * * The first Symbol type is the constant `ADJACENT_FILE`. If this Symbol is * returned, the system assumes that next to the source file in question is * a file of the same name with a .graphql extension. This file should be * made of the GraphQL IDL schema definitions for the object types being * created. * * Example: * ```js * static get SCHEMA(): string | Symbol { * return GQLBase.ADJACENT_FILE * } * ``` * * The primary advantage of this approach is allowing an outside editor that * provides syntax highlighting rather than returning a string from the * SCHEMA getter. * * Alternatively, the static method IDLFilePath can be used to point to an * alternate location where the GraphQL IDL file resides. The extension can * also be changed from .graphql to something else if need be using this * method. * * Example: * ```js * static get SCHEMA(): string | Symbol { * return GQLBase.IDLFilePath('/path/to/file', '.idl') * } * ``` * * @instance * @memberof GQLBase * @method ⬇︎⠀SCHEMA * @readonly * @static * * @return {string|Symbol} a valid IDL string or one of the Symbols * described above. * * @see {@link GQLBase#ADJACENT_FILE} * @see {@link GQLBase#IDLFilePath} */ static get SCHEMA(): string | Symbol { return '' } /** * This method should return a promise that resolves to an object of * functions matching the names of the mutation operations. These are to be * injected into the root object when used by `GQLExpressMiddleware`. * * @instance * @memberof GQLBase * @method ⌾⠀MUTATORS * @readonly * @static * * @param {Object} requestData typically an object containing three * properties; {req, res, gql} * @return {Promise} a promise that resolves to an object; see above for more * information. */ static async MUTATORS(requestData: Object): Promise&lt;Object> { // define in base class return {}; } /** * This method should return a promise that resolves to an object of * functions matching the names of the query operations. These are to be * injected into the root object when used by `GQLExpressMiddleware`. * * @instance * @memberof GQLBase * @method ⌾⠀RESOLVERS * @readonly * @static * * @param {Object} requestData typically an object containing three * properties; {req, res, gql} * @return {Promise} a promise that resolves to an object; see above for more * information. */ static async RESOLVERS(requestData: Object): Promise&lt;Object> { // define in base class return {}; } /** * @see {@link GQLBase#SCHEMA} * * @memberof GQLBase * @method ⬇︎⠀ADJACENT_FILE * @static * @const * * @return {Symbol} the Symbol, when returned from SCHEMA, causes * the logic to load an IDL Schema from an associated file with a .graphql * extension and bearing the same name. */ static get ADJACENT_FILE(): Symbol { return Symbol.for('.graphql file located adjacent to source') } /** * Determines the default type targeted by this GQLBase class. Any * type will technically be valid but only will trigger special behavior * * @memberof GQLBase * @method ⬇︎⠀GQL_TYPE * @static * @const * * @return {Function} a type, such as `GraphQLObjectType` or * `GraphQLInterfaceType` */ static get GQL_TYPE(): Function { return GraphQLObjectType; } /** * Creates an appropriate Symbol crafted with the right data for use by * the IDLFileHandler class below. * * @static * @memberof GQLBase * @method ⌾⠀IDLFilePath * * @param {string} path a path to the IDL containing file * @param {string} [extension='.graphql'] an extension, including the * prefixed period, that will be added to the supplied path should it not * already exist. * @return Symbol * * @see {@link GQLBase#SCHEMA} */