1 | <!DOCTYPE html>
|
2 | <html lang="en">
|
3 | <head>
|
4 | <meta charset="utf-8">
|
5 | <meta name="viewport" content="width=device-width,initial-scale=1">
|
6 | <title>SyntaxTree.js - Documentation</title>
|
7 |
|
8 | <script src="scripts/prettify/prettify.js"></script>
|
9 | <script src="scripts/prettify/lang-css.js"></script>
|
10 | |
11 |
|
12 |
|
13 | <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
|
14 | <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
15 | <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
16 | </head>
|
17 | <body>
|
18 |
|
19 | <input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
20 | <label for="nav-trigger" class="navicon-button x">
|
21 | <div class="navicon"></div>
|
22 | </label>
|
23 |
|
24 | <label for="nav-trigger" class="overlay"></label>
|
25 |
|
26 | <nav>
|
27 | <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AwaitingPromiseError.html">AwaitingPromiseError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError.html#%25E2%258C%25BE%25E2%25A0%2580asyncFn">⌾⠀asyncFn</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError.html#%25E2%258C%25BE%25E2%25A0%2580setPromise">⌾⠀setPromise</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AwaitingPromiseError_exports.AwaitingPromiseError.html">AwaitingPromiseError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="AwaitingPromiseError_exports.AwaitingPromiseError.html#setPromise">setPromise</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Deferred_exports.Deferred.html">Deferred</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DirectTypeAdd.html">DirectTypeAdd</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="FunctionExecutionError_FunctionExecutionError.html">FunctionExecutionError</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLBase.html">GQLBase</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.apiDocs">apiDocs</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getMergedRoot">⌾⠀getMergedRoot</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getProp">⌾⠀getProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580getResolver">⌾⠀getResolver</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580IDLFilePath">⌾⠀IDLFilePath</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580MUTATORS">⌾⠀MUTATORS</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580RESOLVERS">⌾⠀RESOLVERS</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%258C%25BE%25E2%25A0%2580setupModel">⌾⠀setupModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580handler">⬇︎⠀handler</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580SCHEMA">⬇︎⠀SCHEMA</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580applyAutoProps">⌾⠀applyAutoProps</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580callProp">⌾⠀callProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580extendModel">⌾⠀extendModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getModel">⌾⠀getModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getProp">⌾⠀getProp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580getResolver">⌾⠀getResolver</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%258C%25BE%25E2%25A0%2580setModel">⌾⠀setModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%25AC%2586%25EF%25B8%258E%25E2%25A0%2580requestData">⬆︎⠀requestData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580requestData">⬇︎⠀requestData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#~deleteProperty">deleteProperty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBase.html#~set">set</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLBase.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLEnum.html">GQLEnum</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#..get">.get</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#..set">.set</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.valueFor">valueFor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580enums">⬇︎⠀enums</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580name">⬇︎⠀name</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580value">⬇︎⠀value</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#.%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580values">⬇︎⠀values</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLEnum.html#GenerateEnumsProxyHandler">GenerateEnumsProxyHandler</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html">GQLExpressMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#.clearCache">clearCache</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#.%25E2%258C%25BE%25E2%25A0%2580generateSchemaSDL">⌾⠀generateSchemaSDL</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#astMiddleware">astMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#schemaMiddleware">schemaMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%258C%25BE%25E2%25A0%2580customMiddleware">⌾⠀customMiddleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580middleware">⬇︎⠀middleware</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580middlewareWithoutGraphiQL">⬇︎⠀middlewareWithoutGraphiQL</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLExpressMiddleware.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580schema">⬇︎⠀schema</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLExpressMiddleware.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLInterface.html">GQLInterface</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLInterface.html#.%25E2%258C%25BE%25E2%25A0%2580resolveType">⌾⠀resolveType</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="GQLScalar.html">GQLScalar</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.parseLiteral">parseLiteral</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.parseValue">parseValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLScalar.html#.serialize">serialize</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IDLFileHandler.html">IDLFileHandler</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getFile">⌾⠀getFile</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getSchema">⌾⠀getSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IDLFileHandler.html#%25E2%258C%25BE%25E2%25A0%2580getSyntaxTree">⌾⠀getSyntaxTree</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IDLFileHandler.%25E2%258E%2586%25E2%25A0%2580constructor.html">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ModuleParser.html">ModuleParser</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#.%25E2%258C%25BE%25E2%25A0%2580arrayToPattern">⌾⠀arrayToPattern</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#.%25E2%258C%25BE%25E2%25A0%2580checkForPackageExtensions">⌾⠀checkForPackageExtensions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580findGQLBaseClasses">⌾⠀findGQLBaseClasses</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580importClass">⌾⠀importClass</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580parse">⌾⠀parse</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#%25E2%258C%25BE%25E2%25A0%2580parseSync">⌾⠀parseSync</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258C%25BE%25E2%25A0%2580walk">⌾⠀walk</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258C%25BE%25E2%25A0%2580walkSync">⌾⠀walkSync</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ModuleParser.html#~%25E2%258E%2586%25E2%25A0%2580constructor">⎆⠀constructor</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ModuleParser.exports.ModuleParser.html">exports.ModuleParser</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="SchemaUtils.html">SchemaUtils</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580createMergedRoot">⌾⠀createMergedRoot</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectComments">⌾⠀injectComments</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectEnums">⌾⠀injectEnums</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectInterfaceResolvers">⌾⠀injectInterfaceResolvers</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SchemaUtils.html#.%25E2%258C%25BE%25E2%25A0%2580injectScalars">⌾⠀injectScalars</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="SyntaxTree.html">SyntaxTree</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyDocument">⌾⠀EmptyDocument</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyMutation">⌾⠀EmptyMutation</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580EmptyQuery">⌾⠀EmptyQuery</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findDefinition">⌾⠀findDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findField">⌾⠀findField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580findInASTArrayByNameValue">⌾⠀findInASTArrayByNameValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580from">⌾⠀from</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580fromAST">⌾⠀fromAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258C%25BE%25E2%25A0%2580fromSchema">⌾⠀fromSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#.%25E2%258E%2586%25E2%25A0%2580constructor">⎆⠀constructor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580appendDefinitions">⌾⠀appendDefinitions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580consumeDefinition">⌾⠀consumeDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580find">⌾⠀find</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580findEnumDefinition">⌾⠀findEnumDefinition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580setAST">⌾⠀setAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580toString">⌾⠀toString</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%258C%25BE%25E2%25A0%2580updateAST">⌾⠀updateAST</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%25AC%2586%25EF%25B8%258E%25E2%25A0%2580ast">⬆︎⠀ast</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="SyntaxTree.html#%25E2%25AC%2587%25EF%25B8%258E%25E2%25A0%2580ast">⬇︎⠀ast</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="utils.Deferred.html">Deferred</a></span></li><li class="nav-heading">Namespaces</li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="decorators.html">decorators</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#.%25E2%258C%25BE%25E2%25A0%2580extractBits">⌾⠀extractBits</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580AdjacentSchema">.🏷⠀AdjacentSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580FileSchema">.🏷⠀FileSchema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Getters">.🏷⠀Getters</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Properties">.🏷⠀Properties</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Schema">.🏷⠀Schema</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#..%25F0%259F%258F%25B7%25E2%25A0%2580Setters">.🏷⠀Setters</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="decorators.html#~decorate">decorate</a></span></li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="GQLBaseEnv.html">GQLBaseEnv</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="GQLBaseEnv.html#~notDefined">notDefined</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#applyTags">applyTags</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#AsyncFunctionExecutionError">AsyncFunctionExecutionError</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_API_DOCS">CHECK_API_DOCS</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_RESOLVERS">CHECK_RESOLVERS</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECK_SCHEMA">CHECK_SCHEMA</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CHECKLIST">CHECKLIST</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#FunctionExecutionError">FunctionExecutionError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getChecklist">getChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#hasChecklist">hasChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#newChecklist">newChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setChecklist">setChecklist</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#types">types</a></span></li>
|
28 | </nav>
|
29 |
|
30 | <div id="main">
|
31 |
|
32 | <h1 class="page-title">SyntaxTree.js</h1>
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | <section>
|
41 | <article>
|
42 | <pre class="prettyprint source linenums"><code>// @flow
|
43 | // @module SyntaxTree
|
44 |
|
45 | import { typeOf } from 'ne-types'
|
46 | import { print, parse } from 'graphql'
|
47 | import { merge } from 'lodash'
|
48 | import { LatticeLogs as ll } from './utils'
|
49 |
|
50 | import type { GraphQLObjectType } from 'graphql/type/definition'
|
51 | import type {
|
52 | ObjectTypeDefinitionNode,
|
53 | InterfaceTypeDefinitionNode,
|
54 | EnumTypeDefinitionNode,
|
55 | UnionTypeDefinitionNode,
|
56 | FieldDefinitionNode,
|
57 | TypeDefinitionNode,
|
58 | TypeNode
|
59 | } from 'graphql/language/ast'
|
60 |
|
61 |
|
62 | // Shorthand for the key storing the internal AST
|
63 | // @prop
|
64 | const AST_KEY = Symbol.for('Internal AST Storage Key');
|
65 |
|
66 | /**
|
67 | * A parser and processor of GraphQL IDL Abstract Syntax Trees. Used to combine
|
68 | * a set of {@link GQLBase} class instances.
|
69 | *
|
70 | * @class SyntaxTree
|
71 | */
|
72 | export class SyntaxTree
|
73 | {
|
74 | /**
|
75 | * Constructs a new `SyntaxTree` object. If a string schema is supplied or
|
76 | * an already parsed AST object, either of which is valid GraphQL IDL, then
|
77 | * its parsed AST will be the internals of this object.
|
78 | *
|
79 | * @constructor
|
80 | * @memberof SyntaxTree
|
81 | * @method ⎆⠀constructor
|
82 | *
|
83 | * @param {string|Object|SyntaxTree} schemaOrASTOrST if supplied the tree
|
84 | * will be constructed with the contents of the data. If a string of IDL is
|
85 | * given, it will be parsed. If an AST is given, it will be verified. If a
|
86 | * SyntaxTree is supplied, it will be copied.
|
87 | */
|
88 | constructor(schemaOrASTOrST?: string | Object | SyntaxTree) {
|
89 | // $ComputedType
|
90 | this[AST_KEY] = {};
|
91 |
|
92 | if (schemaOrASTOrST) {
|
93 | this.setAST(schemaOrASTOrST);
|
94 | }
|
95 | }
|
96 |
|
97 | /**
|
98 | * Getter that retrieves the abstract syntax tree created by `graphql.parse`
|
99 | * when it is presented with a valid string of IDL.
|
100 | *
|
101 | * @instance
|
102 | * @memberof SyntaxTree
|
103 | * @method ⬇︎⠀ast
|
104 | *
|
105 | * @return {Object} a GraphQL AST object
|
106 | */
|
107 | get ast(): Object {
|
108 | // $ComputedType
|
109 | return this[AST_KEY];
|
110 | }
|
111 |
|
112 | /**
|
113 | * Setter that assigns the abstract syntax tree, typically created by
|
114 | * `graphql.parse` when given a valid string of IDL.
|
115 | *
|
116 | * @instance
|
117 | * @memberof SyntaxTree
|
118 | * @method ⬆︎⠀ast
|
119 | *
|
120 | * @param {Object} value a valid AST object. Other operations will act
|
121 | * in an undefined manner should this object not be a valid AST
|
122 | */
|
123 | set ast(value: Object): void {
|
124 | // $ComputedType
|
125 | this[AST_KEY] = value;
|
126 | }
|
127 |
|
128 | /**
|
129 | * Sets the underlying AST object with either schema which will be parsed
|
130 | * into a valid AST or an existing AST. Previous ast values will be erased.
|
131 | *
|
132 | * @instance
|
133 | * @memberof SyntaxTree
|
134 | * @method ⌾⠀setAST
|
135 | *
|
136 | * @param {string|Object} schemaOrAST a valid GraphQL IDL schema or a
|
137 | * previosuly parsed or compatible GraphQL IDL AST object.
|
138 | * @return {SyntaxTree} this for inlining.
|
139 | */
|
140 | setAST(schemaOrASTOrST: string|Object|SyntaxTree): SyntaxTree {
|
141 | // $ComputedType
|
142 | this[AST_KEY] = {};
|
143 |
|
144 | const type = typeOf(schemaOrASTOrST);
|
145 | let ast: Object;
|
146 | let st: SyntaxTree;
|
147 |
|
148 | switch (type) {
|
149 | case String.name:
|
150 | try {
|
151 | ast = parse((schemaOrASTOrST: any));
|
152 |
|
153 | merge(this.ast, ast);
|
154 | }
|
155 | catch (ignore) { /* Ignore this error */ }
|
156 |
|
157 | break;
|
158 | case Object.name:
|
159 | ast = (schemaOrASTOrST: any);
|
160 |
|
161 | try {
|
162 | ast = parse(print(ast));
|
163 | merge(this.ast, ast);
|
164 | }
|
165 | catch (ignore) { /* Ignore this error */ }
|
166 |
|
167 | break;
|
168 | case SyntaxTree.name:
|
169 | st = (schemaOrASTOrST: any);
|
170 |
|
171 | merge(this.ast, st.ast);
|
172 |
|
173 | break;
|
174 | }
|
175 |
|
176 | return this;
|
177 | }
|
178 |
|
179 | /**
|
180 | * As passthru update method that works on the internal AST object. If
|
181 | * an error occurs, the update is skipped. An error can occur if adding the
|
182 | * changes would make the AST invalid. In such a case, the error is logged
|
183 | * to the error console.
|
184 | *
|
185 | * @instance
|
186 | * @memberof SyntaxTree
|
187 | * @method ⌾⠀updateAST
|
188 | *
|
189 | * @param {Object} ast an existing GraphQL IDL AST object that will be
|
190 | * merged on top of the existing tree using _.merge()
|
191 | * @return {SyntaxTree} this for inlining.
|
192 | */
|
193 | updateAST(ast: Object): SyntaxTree {
|
194 | if (typeOf(ast) === Object.name) {
|
195 | let newAST = merge({}, this.ast, ast);
|
196 |
|
197 | try {
|
198 | print(newAST);
|
199 | this.ast = merge(this.ast, ast);
|
200 | }
|
201 | catch (error) {
|
202 | ll.error('[SyntaxTree] Failed to updateAST with %o', ast);
|
203 | ll.error('Resulting object would be %o', newAST);
|
204 | ll.error(error);
|
205 | }
|
206 | }
|
207 |
|
208 | return this;
|
209 | }
|
210 |
|
211 | /**
|
212 | * Appends all definitions from another AST to this one. The method will
|
213 | * actually create a copy using SyntaxTree.from() so the input types can
|
214 | * be any one of a valid GraphQL IDL schema string, a GraphQL IDL AST or
|
215 | * another SyntaxTree object instance.
|
216 | *
|
217 | * Definitions of the same name but different kinds will be replaced by the
|
218 | * new copy. Those of the same kind and name will be merged (TODO handle more
|
219 | * than ObjectTypeDefinition kinds when merging; currently other types are
|
220 | * overwritten).
|
221 | *
|
222 | * @instance
|
223 | * @memberof SyntaxTree
|
224 | * @method ⌾⠀appendDefinitions
|
225 | *
|
226 | * @param {string|Object|SyntaxTree} schemaOrASTOrST an instance of one of
|
227 | * the valid types for SyntaxTree.from() that can be used to create or
|
228 | * duplicate the source from which to copy definitions.
|
229 | * @return {SyntaxTree} this for inlining
|
230 | */
|
231 | appendDefinitions(schemaOrASTOrST: string | Object | SyntaxTree): SyntaxTree {
|
232 | const source = SyntaxTree.from(schemaOrASTOrST);
|
233 | const set = new Set();
|
234 |
|
235 | this.ast.definitions.map((definition) => {
|
236 | set.add(definition.name.value);
|
237 | })
|
238 |
|
239 | if (source && source.ast.definitions && this.ast.definitions) {
|
240 | for (let theirs of (source: any)) {
|
241 | let name = theirs.name.value;
|
242 | let ours = this.find(name);
|
243 | let index = ours && this.ast.definitions.indexOf(ours) || -1;
|
244 |
|
245 | // We don't yet have one with that name
|
246 | if (!set.has(name)) {
|
247 | set.add(name);
|
248 | this.ast.definitions.push(theirs);
|
249 | }
|
250 |
|
251 | // We do have one with that name
|
252 | else {
|
253 | // The kinds aren't the same, just replace theirs with ours
|
254 | if (theirs.kind !== ours.kind) {
|
255 | // replace with the new one
|
256 | this.ast.definitions[index] = theirs;
|
257 | }
|
258 |
|
259 | // The kinds are the same, lets just merge their fields
|
260 | else {
|
261 | // merge the properties of the same types.
|
262 | switch (theirs.kind) {
|
263 | case 'ObjectTypeDefinition':
|
264 | ours.interfaces = [].concat(ours.interfaces, theirs.interfaces)
|
265 | ours.directives = [].concat(ours.directives, theirs.directives)
|
266 | ours.fields = [].concat(ours.fields, theirs.fields)
|
267 | break;
|
268 | default:
|
269 | // Since we don't support other types yet. Let's replace
|
270 | this.ast.definitions[index] = theirs;
|
271 | break;
|
272 | }
|
273 | }
|
274 | }
|
275 | }
|
276 | }
|
277 |
|
278 | return this;
|
279 | }
|
280 |
|
281 | /**
|
282 | * This method finds the Query type definitions in the supplied AST or
|
283 | * SyntaxTree objects, takes its defined fields and adds it to the current
|
284 | * instances. If this instance does not have a Query type defined but the
|
285 | * supplied object does, then the supplied one is moved over. If neither
|
286 | * has a query handler, then nothing happens.
|
287 | *
|
288 | * NOTE this *removes* the Query type definition from the supplied AST or
|
289 | * SyntaxTree object.
|
290 | *
|
291 | * @instance
|
292 | * @memberof SyntaxTree
|
293 | * @method ⌾⠀consumeDefinition
|
294 | *
|
295 | * @param {Object|SyntaxTree} astOrSyntaxTree a valid GraphQL IDL AST or
|
296 | * an instance of SyntaxTree that represents one.
|
297 | * @param {string|RegExp} definitionType a valid search input as would be
|
298 | * accepted for the #find() method of this object.
|
299 | * @return {SyntaxTree} returns this for inlining
|
300 | */
|
301 | consumeDefinition(
|
302 | astOrSyntaxTree: Object | SyntaxTree,
|
303 | definitionType: string | RegExp = "Query"
|
304 | ): SyntaxTree {
|
305 | if (!astOrSyntaxTree || !this.ast || !this.ast.definitions) { return this }
|
306 |
|
307 | const tree = typeOf(SyntaxTree) === SyntaxTree.name
|
308 | ? astOrSyntaxTree
|
309 | : SyntaxTree.from(astOrSyntaxTree);
|
310 | let left = this.find(definitionType);
|
311 | let right = tree && tree.find(definitionType) || null;
|
312 |
|
313 | if (!tree) {
|
314 | ll.error('There seems to be something wrong with your tree')
|
315 | ll.error(new Error('Missing tree; continuing...'));
|
316 | return this;
|
317 | }
|
318 |
|
319 | if (!right) { return this }
|
320 |
|
321 | if (!left) {
|
322 | this.ast.definitions.push(right);
|
323 |
|
324 | // Remove the copied definition from the source
|
325 | tree.ast.definitions.splice(tree.ast.definitions.indexOf(right), 1);
|
326 |
|
327 | return this;
|
328 | }
|
329 |
|
330 | // TODO support other types aside from ObjectTypeDefinitions
|
331 | // TODO see if there is a better way to achieve this with built-in
|
332 | // graphql code someplace
|
333 | switch(left.kind) {
|
334 | case 'ObjectTypeDefinition':
|
335 | if (left.interfaces && right.interfaces) {
|
336 | left.interfaces = [].concat(left.interfaces, right.interfaces);
|
337 | }
|
338 |
|
339 | if (left.directives && right.directives) {
|
340 | left.directives = [].concat(left.directives, right.directives);
|
341 | }
|
342 |
|
343 | if (left.fields && right.fields) {
|
344 | left.fields = [].concat(left.fields, right.fields);
|
345 | }
|
346 |
|
347 | break;
|
348 | default:
|
349 | break;
|
350 | }
|
351 |
|
352 | // Remove the copied definition from the source
|
353 | tree.ast.definitions.splice(tree.ast.definitions.indexOf(right), 1);
|
354 |
|
355 | return this;
|
356 | }
|
357 |
|
358 | /**
|
359 | * When iterating over an instance of SyntaxTree, you are actually
|
360 | * iterating over the definitions of the SyntaxTree if there are any;
|
361 | *
|
362 | * @instance
|
363 | * @memberof SyntaxTree
|
364 | * @method *[Symbol.iterator]
|
365 | *
|
366 | * @return {TypeDefinitionNode} an instance of a TypeDefinitionNode; see
|
367 | * graphql/language/ast.js.flow for more information
|
368 | * @ComputedType
|
369 | */
|
370 | *[Symbol.iterator](): TypeDefinitionNode {
|
371 | if (this[AST_KEY].definitions) {
|
372 | return yield* this[AST_KEY].definitions;
|
373 | }
|
374 | else {
|
375 | return yield* this;
|
376 | }
|
377 | }
|
378 |
|
379 | /**
|
380 | * Getter that builds a small outline object denoting the schema being
|
381 | * processed. If you have a schema that looks like the following:
|
382 | *
|
383 | * ```javascript
|
384 | * let st = SyntaxTree.from(`
|
385 | * type Contrived {
|
386 | * name: String
|
387 | * age: Int
|
388 | * }
|
389 | *
|
390 | * type Query {
|
391 | * getContrived: Contrived
|
392 | * }
|
393 | * `)
|
394 | * let outline = st.outline
|
395 | * ```
|
396 | *
|
397 | * You will end up with an object that looks like the following:
|
398 | *
|
399 | * ```javascript
|
400 | * {
|
401 | * Contrived: { name: 'String', age: 'Int' },
|
402 | * Query: { getContrived: 'Contrived' }
|
403 | * }
|
404 | * ```
|
405 | *
|
406 | * As may be evidenced by the example above, the name of the type is
|
407 | * represented by an object where the name of each field (sans arguments)
|
408 | * is mapped to a string denoting the type.
|
409 | */
|
410 | get outline(): Object {
|
411 | let outline = {}
|
412 | let interfaces = Symbol.for('interfaces')
|
413 |
|
414 | // $FlowFixMe
|
415 | for (let definition of this) {
|
416 | let out
|
417 |
|
418 | switch (definition.kind) {
|
419 | case 'InterfaceTypeDefinition':
|
420 | case 'ObjectTypeDefinition':
|
421 | out = outline[definition.name.value] = {}
|
422 | definition.fields.forEach(
|
423 | field => {
|
424 | if (field.type.kind === 'NamedType')
|
425 | out[field.name.value] = field.type.name.value
|
426 | else if (field.type.kind === 'ListType')
|
427 | out[field.name.value] = field.type.type.name.value
|
428 | }
|
429 | )
|
430 |
|
431 | if (definition.interfaces) {
|
432 | // $FlowFixMe
|
433 | out = (out[interfaces] = out[interfaces] || [])
|
434 |
|
435 | definition.interfaces.forEach(
|
436 | _interface => out.push(_interface.name.value)
|
437 | )
|
438 | }
|
439 |
|
440 | break;
|
441 |
|
442 | case 'EnumTypeDefinition':
|
443 | out = outline[definition.name.value] = []
|
444 | definition.values.forEach(
|
445 | value => out[value.name.value] = value.name.value
|
446 | )
|
447 | break;
|
448 |
|
449 | case 'UnionTypeDefinition':
|
450 | out = outline[definition.name.value] = []
|
451 | definition.types.forEach(
|
452 | type => out.push(type.name.value)
|
453 | )
|
454 | break;
|
455 | }
|
456 | }
|
457 |
|
458 | return outline
|
459 | }
|
460 |
|
461 | /**
|
462 | * Iterate through the definitions of the AST if there are any. For each
|
463 | * definition the name property's value field is compared to the supplied
|
464 | * definitionName. The definitionName can be a string or a regular
|
465 | * expression if finer granularity is desired.
|
466 | *
|
467 | * @instance
|
468 | * @memberof SyntaxTree
|
469 | * @method ⌾⠀find
|
470 | *
|
471 | * @param {string|RegExp} definitionName a string or regular expression used
|
472 | * to match against the definition name field in a given AST.
|
473 | * @return {Object|null} a reference to the internal definition field or
|
474 | * null if one with a matching name could not be found.
|
475 | */
|
476 | find(definitionName: string|RegExp): Object | null {
|
477 | // $ComputedType
|
478 | return SyntaxTree.findDefinition(this[AST_KEY], definitionName);
|
479 | }
|
480 |
|
481 | /**
|
482 | * SyntaxTree instances that are toString()'ed will have the graphql method
|
483 | * print() called on them to convert their internal structures back to a
|
484 | * GraphQL IDL schema syntax. If the object is in an invalid state, it WILL
|
485 | * throw an error.
|
486 | *
|
487 | * @instance
|
488 | * @memberof SyntaxTree
|
489 | * @method ⌾⠀toString
|
490 | *
|
491 | * @return {string} the AST for the tree parsed back into a string
|
492 | */
|
493 | toString(): string {
|
494 | // $ComputedType
|
495 | return print(this[AST_KEY]);
|
496 | }
|
497 |
|
498 | /**
|
499 | * A runtime constant denoting a query type.
|
500 | *
|
501 | * @type {string}
|
502 | * @static
|
503 | * @memberof SyntaxTree
|
504 | * @method ⬇︎⠀QUERY
|
505 | * @readonly
|
506 | * @const
|
507 | */
|
508 | static get QUERY(): string { return 'Query' }
|
509 |
|
510 | /**
|
511 | * A runtime constant denoting a mutation type.
|
512 | *
|
513 | * @type {string}
|
514 | * @static
|
515 | * @memberof SyntaxTree
|
516 | * @method ⬇︎⠀MUTATION
|
517 | * @readonly
|
518 | * @const
|
519 | */
|
520 | static get MUTATION(): string { return 'Mutation' }
|
521 |
|
522 | /**
|
523 | * A runtime constant denoting a subscription type.
|
524 | *
|
525 | * @type {string}
|
526 | * @static
|
527 | * @memberof SyntaxTree
|
528 | * @method SUBSCRIPTION
|
529 | * @readonly
|
530 | * @const
|
531 | */
|
532 | static get SUBSCRIPTION(): string { return 'Subscription' }
|
533 |
|
534 | /**
|
535 | * Returns the `constructor` name. If invoked as the context, or `this`,
|
536 | * object of the `toString` method of `Object`'s `prototype`, the resulting
|
537 | * value will be `[object MyClass]`, given an instance of `MyClass`
|
538 | *
|
539 | * @method ⌾⠀[Symbol.toStringTag]
|
540 | * @memberof SyntaxTree
|
541 | *
|
542 | * @return {string} the name of the class this is an instance of
|
543 | * @ComputedType
|
544 | */
|
545 | get [Symbol.toStringTag]() { return this.constructor.name }
|
546 |
|
547 | /**
|
548 | * Applies the same logic as {@link #[Symbol.toStringTag]} but on a static
|
549 | * scale. So, if you perform `Object.prototype.toString.call(MyClass)`
|
550 | * the result would be `[object MyClass]`.
|
551 | *
|
552 | * @method ⌾⠀[Symbol.toStringTag]
|
553 | * @memberof SyntaxTree
|
554 | * @static
|
555 | *
|
556 | * @return {string} the name of this class
|
557 | * @ComputedType
|
558 | */
|
559 | static get [Symbol.toStringTag]() { return this.name }
|
560 |
|
561 | /**
|
562 | * Given one of, a valid GraphQL IDL schema string, a valid GraphQL AST or
|
563 | * an instance of SyntaxTree, the static from() method will create a new
|
564 | * instance of the SyntaxTree with the values you provide.
|
565 | *
|
566 | * @static
|
567 | * @memberof SyntaxTree
|
568 | * @method ⌾⠀from
|
569 | *
|
570 | * @param {String|Object|SyntaxTree} mixed an instance of one of the valid
|
571 | * types specified above. Everything else will result in a null value.
|
572 | * @return {SyntaxTree} a newly created and populated instance of SyntaxTree
|
573 | * or null if an invalid type was supplied for mixed.
|
574 | */
|
575 | static from(mixed: string | Object | SyntaxTree): SyntaxTree | null {
|
576 | let schema: string;
|
577 | let ast: Object;
|
578 |
|
579 | switch (typeOf(mixed)) {
|
580 | case String.name:
|
581 | schema = (mixed: any);
|
582 | try { parse(schema) } catch(error) { ll.error(error); return null; }
|
583 |
|
584 | return SyntaxTree.fromSchema(String(schema));
|
585 | case Object.name:
|
586 | ast = (mixed: any);
|
587 | try { print(ast) } catch(error) { return null; }
|
588 |
|
589 | return SyntaxTree.fromAST(ast);
|
590 | case SyntaxTree.name:
|
591 | schema = mixed.toString();
|
592 |
|
593 | return SyntaxTree.from(schema);
|
594 | default:
|
595 | return null;
|
596 | }
|
597 | }
|
598 |
|
599 | /**
|
600 | * Generates a new instance of SyntaxTree from the supplied, valid, GraphQL
|
601 | * schema. This method does not perform try/catch validation and if an
|
602 | * invalid GraphQL schema is supplied an error will be thrown.
|
603 | *
|
604 | * @static
|
605 | * @memberof SyntaxTree
|
606 | * @method ⌾⠀fromSchema
|
607 | *
|
608 | * @param {string} schema a valid GraphQL IDL schema string.
|
609 | * @return {SyntaxTree} a new instance of SyntaxTree initialized with a
|
610 | * parsed response from require('graphql').parse().
|
611 | */
|
612 | static fromSchema(schema: string): SyntaxTree {
|
613 | const ast = parse(schema);
|
614 | let tree = new SyntaxTree(ast);
|
615 |
|
616 | return tree;
|
617 | }
|
618 |
|
619 | /**
|
620 | * Generates a new instance of SyntaxTree from the supplied, valid, GraphQL
|
621 | * schema. This method does not perform try/catch validation and if an
|
622 | * invalid GraphQL schema is supplied an error will be thrown.
|
623 | *
|
624 | * @static
|
625 | * @memberof SyntaxTree
|
626 | * @method ⌾⠀fromAST
|
627 | *
|
628 | * @param {object} ast a valid GraphQL AST object.
|
629 | * @return {SyntaxTree} a new instance of SyntaxTree initialized with a
|
630 | * supplied abstract syntax tree generated by require('graphql').parse() or
|
631 | * other compatible method.
|
632 | */
|
633 | static fromAST(ast: Object): SyntaxTree | null {
|
634 | const source = parse(print(ast));
|
635 | let tree = new SyntaxTree(source);
|
636 |
|
637 | return source ? tree : null;
|
638 | }
|
639 |
|
640 | /**
|
641 | * Iterate through the definitions of the AST if there are any. For each
|
642 | * definition the name property's value field is compared to the supplied
|
643 | * definitionName. The definitionName can be a string or a regular
|
644 | * expression if finer granularity is desired.
|
645 | *
|
646 | * @static
|
647 | * @memberof SyntaxTree
|
648 | * @method ⌾⠀findDefinition
|
649 | *
|
650 | * @param {Object} ast an abstract syntax tree object created from a GQL SDL
|
651 | * @param {string|RegExp} definitionName a string or regular expression used
|
652 | * to match against the definition name field in a given AST.
|
653 | * @return {Object|null} a reference to the internal definition field or
|
654 | * null if one with a matching name could not be found.
|
655 | */
|
656 | static findDefinition(ast: Object, definitionName: string | RegExp) {
|
657 | return this.findInASTArrayByNameValue(
|
658 | ast.definitions,
|
659 | definitionName
|
660 | );
|
661 | }
|
662 |
|
663 | /**
|
664 | * Iterate through the fields of a definition AST if there are any. For each
|
665 | * field, the name property's value field is compared to the supplied
|
666 | * fieldName. The fieldName can be a string or a regular expression if
|
667 | * finer granularity is desired.
|
668 | *
|
669 | * Before iterating over the fields, however, the definition is found using
|
670 | * `SyntaxTree#findDefinition`. If either the field or definition are not
|
671 | * found, null is returned.
|
672 | *
|
673 | * @static
|
674 | * @memberof SyntaxTree
|
675 | * @method ⌾⠀findField
|
676 | * @since 2.7.0
|
677 | *
|
678 | * @param {Object} ast an abstract syntax tree object created from a GQL SDL
|
679 | * @param {string|RegExp} definitionName a string or regular expression used
|
680 | * to match against the definition name field in a given AST.
|
681 | * @param {string|RegExp} fieldName a string or regular expression used
|
682 | * to match against the field name field in a given AST.
|
683 | * @return {Object|null} an object containing two keys, the first being
|
684 | * `field` which points to the requested AST definition field. The second
|
685 | * being `meta` which contains three commonly requested bits of data; `name`,
|
686 | * `type` and `nullable`. Non-nullable fields have their actual type wrapped
|
687 | * in a `NonNullType` GraphQL construct. The actual field type is contained
|
688 | * within. The meta object surfaces those values for easy use.
|
689 | */
|
690 | static findField(
|
691 | ast: Object,
|
692 | definitionName: string | RegExp,
|
693 | fieldName: string | RegExp
|
694 | ) {
|
695 | const definition = this.findDefinition(ast, definitionName)
|
696 | let meta;
|
697 |
|
698 | if (!definition || !definition.fields) {
|
699 | return null;
|
700 | }
|
701 |
|
702 | const field = this.findInASTArrayByNameValue(definition.fields, fieldName)
|
703 |
|
704 | if (field) {
|
705 | meta = {
|
706 | name: field.name && field.name.value || null,
|
707 | type: field.type && field.type.kind === 'NonNullType'
|
708 | ? field.type.type.name.value
|
709 | : field.type && field.type.name && field.type.name.value || null,
|
710 | nullable: !!(field.type && field.type.kind !== 'NonNullType')
|
711 | }
|
712 | }
|
713 |
|
714 | return { field, meta };
|
715 | }
|
716 |
|
717 | /**
|
718 | * Enum AST definitions operate differently than object type definitions
|
719 | * do. Namely, they do not have a `fields` array but instead have a `values`
|
720 | * array. This wrapper method, first finds the enum definition in the ast
|
721 | * and then searches the values for the named node desired and returns that
|
722 | * or null, if one could not be found.
|
723 | *
|
724 | * @method SyntaxTree#⌾⠀findEnumDefinition
|
725 | * @since 2.7.0
|
726 | *
|
727 | * @param {Object} ast the abstract syntax tree parsed by graphql
|
728 | * @param {string|RegExp} enumDefinitionName a string or regular expression
|
729 | * used to locate the enum definition in the AST.
|
730 | * @param {string|RegExp} enumValueName a string or regular expression used
|
731 | * to locate the value by name in the values of the enum definition.
|
732 | * @return {Object|null} the desired AST node or null if one does not exist
|
733 | */
|
734 | static findEnumDefinition(
|
735 | ast: Object,
|
736 | enumDefinitionName: string | RegExp,
|
737 | enumValueName: string | RegExp
|
738 | ): ?Object {
|
739 | // Fetch the enum definition
|
740 | const definition = this.findDefinition(ast, enumDefinitionName);
|
741 |
|
742 | // Ensure we have one or that it has a values array
|
743 | if (!definition || !definition.values) {
|
744 | return null;
|
745 | }
|
746 |
|
747 | // Return the results of an `findInASTArrayByNameValue()` search of the
|
748 | // aforementioned 'values' array.
|
749 | return this.findInASTArrayByNameValue(
|
750 | definition.values,
|
751 | enumValueName
|
752 | )
|
753 | }
|
754 |
|
755 | /**
|
756 | * A lot of searching in ASTs is filtering through arrays and matching on
|
757 | * subobject properties on each iteration. A common theme is find something
|
758 | * by its `.name.value`. This method simplifies that by taking an array of
|
759 | * AST nodes and searching them for a `.name.value` property that exists
|
760 | * within.
|
761 | *
|
762 | * @static
|
763 | * @memberof SyntaxTree
|
764 | * @method ⌾⠀findInASTArrayByNameValue
|
765 | * @since 2.7.0
|
766 | *
|
767 | * @param {Array} array of mixed AST object nodes containing `name.value`s
|
768 | * @param {string|RegExp} name a string or regular expression used
|
769 | * to match against the node name value
|
770 | * @return {Object|null} the AST leaf if one matches or null otherwise.
|
771 | */
|
772 | static findInASTArrayByNameValue(
|
773 | array: Array<Object>,
|
774 | name: string | RegExp
|
775 | ): ?Object {
|
776 | const isRegExp: boolean = /RegExp/.test(typeOf(name));
|
777 | const regex = !isRegExp
|
778 | // $FlowFixMe
|
779 | ? new RegExp(RegExp.escape(name.toString()))
|
780 | // $FlowFixMe
|
781 | : (name: RegExp);
|
782 | const flags = regex.flags
|
783 | const source = regex.source
|
784 | const reducer = (last,cur,i) => {
|
785 | if (last !== -1) return last;
|
786 | if (!cur || !cur.name || !cur.name.value) return -1;
|
787 | return new RegExp(source, flags).test(cur.name.value) ? i : -1
|
788 | }
|
789 | const index = array.reduce(reducer, -1);
|
790 |
|
791 | return (~index) ? array[index] : null;
|
792 | }
|
793 |
|
794 | /**
|
795 | * Query types in GraphQL are an ObjectTypeDefinition of importance for
|
796 | * placement on the root object. There is utility in creating an empty
|
797 | * one that can be injected with the fields of other GraphQL object query
|
798 | * entries.
|
799 | *
|
800 | * @static
|
801 | * @memberof SyntaxTree
|
802 | * @method ⌾⠀EmptyQuery
|
803 | *
|
804 | * @return {SyntaxTree} an instance of SyntaxTree with a base AST generated
|
805 | * by parsing the graph query, "type Query {}"
|
806 | */
|
807 | static EmptyQuery(): ?SyntaxTree {
|
808 | return SyntaxTree.from(`type ${this.QUERY} {}`);
|
809 | }
|
810 |
|
811 | /**
|
812 | * Mutation types in GraphQL are an ObjectTypeDefinition of importance for
|
813 | * placement on the root object. There is utility in creating an empty
|
814 | * one that can be injected with the fields of other GraphQL object mutation
|
815 | * entries.
|
816 | *
|
817 | * @static
|
818 | * @memberof SyntaxTree
|
819 | * @method ⌾⠀EmptyMutation
|
820 | *
|
821 | * @return {SyntaxTree} an instance of SyntaxTree with a base AST generated
|
822 | * by parsing the graph query, "type Mutation {}"
|
823 | */
|
824 | static EmptyMutation(): ?SyntaxTree {
|
825 | return SyntaxTree.from(`type ${this.MUTATION} {}`);
|
826 | }
|
827 |
|
828 | /**
|
829 | * The starting point for a SyntaxTree that will be built up programmatically.
|
830 | *
|
831 | * @static
|
832 | * @memberof SyntaxTree
|
833 | * @method ⌾⠀EmptyDocument
|
834 | *
|
835 | * @param {string|Object|SyntaxTree} schemaOrASTOrST any valid type taken by
|
836 | * SyntaxTree.from() used to further populate the new empty document
|
837 | * @return {SyntaxTree} an instance of SyntaxTree with no definitions and a
|
838 | * kind set to 'Document'
|
839 | */
|
840 | static EmptyDocument(
|
841 | schemaOrASTOrST?: string | Object | SyntaxTree
|
842 | ): SyntaxTree {
|
843 | let tree = new SyntaxTree();
|
844 |
|
845 | // Due to normal validation methods with ASTs (i.e. converting to string
|
846 | // and then back to an AST object), doing this with an empty document
|
847 | // fails. Therefore, we manually set the document contents here. This allows
|
848 | // toString(), consumeDefinition() and similar methods to still work.
|
849 | tree.ast = {
|
850 | kind: 'Document',
|
851 | definitions: [],
|
852 | loc: {start: 0, end: 0}
|
853 | };
|
854 |
|
855 | if (schemaOrASTOrST) {
|
856 | tree.appendDefinitions(schemaOrASTOrST);
|
857 | }
|
858 |
|
859 | return tree;
|
860 | }
|
861 | }
|
862 |
|
863 | export default SyntaxTree;
|
864 | </code></pre>
|
865 | </article>
|
866 | </section>
|
867 |
|
868 |
|
869 |
|
870 |
|
871 | </div>
|
872 |
|
873 | <br class="clear">
|
874 |
|
875 | <footer>
|
876 | Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Jun 08 2018 19:28:39 GMT-0700 (PDT) using the Minami theme.
|
877 | </footer>
|
878 |
|
879 | <script>prettyPrint();</script>
|
880 | <script src="scripts/linenumber.js"></script>
|
881 | </body>
|
882 | </html>
|