@nyteshade/lattice-legacy
Version:
OO Underpinnings for ease of GraphQL Implementation
872 lines (789 loc) • 65.2 kB
HTML
<!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())
&& !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 <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 <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 <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 && 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 && !(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 && !!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 && (
// 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<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<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<mixed>) {
// $FlowFixMe
let prop = this.getProp(propName, ...args);
let result
if (prop && typeOf(prop) === 'AsyncFunction') {
try {
result = await prop.apply(this, args);
}
catch (error) {
throw new AsyncFunctionExecutionError(error, prop, args, result)
}
}
else if (prop && 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<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<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}
*/