mirror of
https://github.com/zhigang1992/graphql-engine.git
synced 2026-05-22 15:35:20 +08:00
committed by
Vamshi Surabhi
parent
db1a098b3b
commit
128ed2388b
@@ -33,13 +33,14 @@ data RavenOptions
|
||||
|
||||
data ServeOptions
|
||||
= ServeOptions
|
||||
{ soPort :: !Int
|
||||
, soConnParams :: !Q.ConnParams
|
||||
, soTxIso :: !Q.TxIsolation
|
||||
, soRootDir :: !(Maybe String)
|
||||
, soAccessKey :: !(Maybe AccessKey)
|
||||
, soCorsConfig :: !CorsConfig
|
||||
, soWebHook :: !(Maybe T.Text)
|
||||
{ soPort :: !Int
|
||||
, soConnParams :: !Q.ConnParams
|
||||
, soTxIso :: !Q.TxIsolation
|
||||
, soRootDir :: !(Maybe String)
|
||||
, soAccessKey :: !(Maybe AccessKey)
|
||||
, soCorsConfig :: !CorsConfig
|
||||
, soWebHook :: !(Maybe T.Text)
|
||||
, soEnableConsole :: !Bool
|
||||
} deriving (Show, Eq)
|
||||
|
||||
data RavenMode
|
||||
@@ -70,6 +71,7 @@ parseRavenMode = subparser
|
||||
<*> parseAccessKey
|
||||
<*> parseCorsConfig
|
||||
<*> parseWebHook
|
||||
<*> parseEnableConsole
|
||||
|
||||
parseArgs :: IO RavenOptions
|
||||
parseArgs = execParser opts
|
||||
@@ -101,7 +103,7 @@ main = withStdoutLogger ravenLogGen $ \rlogger -> do
|
||||
return $ mkConnInfo rci
|
||||
printConnInfo ci
|
||||
case ravenMode of
|
||||
ROServe (ServeOptions port cp isoL mRootDir mAccessKey corsCfg mWebHook) -> do
|
||||
ROServe (ServeOptions port cp isoL mRootDir mAccessKey corsCfg mWebHook enableConsole) -> do
|
||||
am <- either ((>> exitFailure) . putStrLn) return $
|
||||
mkAuthMode mAccessKey mWebHook
|
||||
initialise ci
|
||||
@@ -109,7 +111,7 @@ main = withStdoutLogger ravenLogGen $ \rlogger -> do
|
||||
pool <- Q.initPGPool ci cp
|
||||
runSpockNoBanner port $ do
|
||||
putStrLn $ "server: running on port " ++ show port
|
||||
spockT id $ app isoL mRootDir rlogger pool am corsCfg
|
||||
spockT id $ app isoL mRootDir rlogger pool am corsCfg enableConsole
|
||||
ROExport -> do
|
||||
res <- runTx ci fetchMetadata
|
||||
either ((>> exitFailure) . printJSON) printJSON res
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
|
||||
module Hasura.Server.App where
|
||||
|
||||
import Control.Concurrent.MVar
|
||||
import Control.Lens
|
||||
import Control.Lens hiding ((.=))
|
||||
import Data.Char (isSpace)
|
||||
import Data.IORef
|
||||
|
||||
@@ -15,7 +16,6 @@ import Crypto.Hash (Digest, SHA1, hash)
|
||||
import Data.Aeson hiding (json)
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import Data.CaseInsensitive (CI (..), original)
|
||||
import qualified Data.FileEmbed as FE
|
||||
import qualified Data.HashMap.Strict as M
|
||||
import qualified Data.String.Conversions as CS
|
||||
import qualified Data.Text as T
|
||||
@@ -28,6 +28,7 @@ import qualified Network.HTTP.Client.TLS as HT
|
||||
import Network.Wai (strictRequestBody)
|
||||
import qualified Network.Wreq as Wq
|
||||
import qualified Network.Wreq.Types as WqT
|
||||
import qualified Data.FileEmbed as FE
|
||||
|
||||
import Web.Spock.Core
|
||||
|
||||
@@ -37,28 +38,28 @@ import qualified Network.Wai.Middleware.Static as MS
|
||||
|
||||
import qualified Data.Text.Encoding.Error as TE
|
||||
import qualified Database.PG.Query as Q
|
||||
import qualified Hasura.GraphQL.Execute as GE
|
||||
import qualified Hasura.GraphQL.Execute.Result as GE
|
||||
import qualified Hasura.GraphQL.Schema as GS
|
||||
import qualified Hasura.GraphQL.Execute as GE
|
||||
import qualified Hasura.GraphQL.Execute.Result as GE
|
||||
import qualified Hasura.GraphQL.Schema as GS
|
||||
|
||||
import Hasura.Prelude hiding (get, put)
|
||||
import Hasura.RQL.DDL.Schema.Table
|
||||
import Hasura.RQL.DML.Explain
|
||||
import Hasura.RQL.DML.QueryTemplate
|
||||
import Hasura.RQL.Types
|
||||
import Hasura.Server.Init
|
||||
import Hasura.Server.Logging
|
||||
import Hasura.Prelude hiding (get, put)
|
||||
import Hasura.Server.Middleware (corsMiddleware,
|
||||
import Hasura.Server.Middleware (corsMiddleware,
|
||||
mkDefaultCorsPolicy)
|
||||
import Hasura.Server.Query
|
||||
import Hasura.Server.Utils
|
||||
import Hasura.SQL.Types
|
||||
|
||||
landingPage :: String
|
||||
landingPage = $(FE.embedStringFile "src-rsr/landing_page.html")
|
||||
|
||||
type RavenLogger = ServerLogger (BL.ByteString, Either QErr BL.ByteString)
|
||||
|
||||
consoleHTML :: T.Text
|
||||
consoleHTML = $(FE.embedStringFile "src-rsr/console.html")
|
||||
|
||||
ravenLogGen :: LogDetailG (BL.ByteString, Either QErr BL.ByteString)
|
||||
ravenLogGen _ (reqBody, res) =
|
||||
|
||||
@@ -361,8 +362,9 @@ app
|
||||
-> Q.PGPool
|
||||
-> AuthMode
|
||||
-> CorsConfig
|
||||
-> Bool
|
||||
-> SpockT IO ()
|
||||
app isoLevel mRootDir logger pool mode corsCfg = do
|
||||
app isoLevel mRootDir logger pool mode corsCfg enableConsole = do
|
||||
cacheRef <- lift $ do
|
||||
pgResp <- liftIO $ runExceptT $ Q.runTx pool (Q.Serializable, Nothing) $ do
|
||||
Q.catchE defaultTxErrorHandler initStateTx
|
||||
@@ -376,13 +378,14 @@ app isoLevel mRootDir logger pool mode corsCfg = do
|
||||
|
||||
liftIO $ putStrLn "HasuraDB is now waiting for connections"
|
||||
|
||||
maybe (return ()) (middleware . MS.staticPolicy . MS.addBase) mRootDir
|
||||
|
||||
-- cors middleware
|
||||
unless (ccDisabled corsCfg) $
|
||||
middleware $ corsMiddleware (mkDefaultCorsPolicy $ ccDomain corsCfg)
|
||||
|
||||
get root $ html $ T.pack landingPage
|
||||
-- API Console and Root Dir
|
||||
if enableConsole then serveApiConsole consoleHTML
|
||||
else maybe (return ()) (middleware . MS.staticPolicy . MS.addBase) mRootDir
|
||||
|
||||
get ("v1/template" <//> var) $ tmpltGetOrDeleteH serverCtx
|
||||
post ("v1/template" <//> var) $ tmpltPutOrPostH serverCtx
|
||||
put ("v1/template" <//> var) $ tmpltPutOrPostH serverCtx
|
||||
@@ -428,3 +431,7 @@ app isoLevel mRootDir logger pool mode corsCfg = do
|
||||
mkQTemplateAction tmpltName tmpltArgs =
|
||||
v1QueryHandler $ RQExecuteQueryTemplate $
|
||||
ExecQueryTemplate (TQueryName tmpltName) tmpltArgs
|
||||
|
||||
serveApiConsole htmlFile = do
|
||||
get root $ redirect "/console"
|
||||
get ("console" <//> wildcard) $ const $ html htmlFile
|
||||
|
||||
@@ -171,3 +171,8 @@ parseWebHook = optional $ strOption ( long "auth-hook" <>
|
||||
metavar "AUTHENTICATION WEB HOOK" <>
|
||||
help "The authentication webhook, required to authenticate requests"
|
||||
)
|
||||
|
||||
parseEnableConsole :: Parser Bool
|
||||
parseEnableConsole = switch ( long "enable-console" <>
|
||||
help "Enable API Console"
|
||||
)
|
||||
|
||||
49
server/src-rsr/console.html
Normal file
49
server/src-rsr/console.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<link rel="icon" type="image/png" href="https://storage.googleapis.com/hasura-graphql-engine/console/assets/favicon.png" />
|
||||
<script>
|
||||
window.__env = {
|
||||
consoleMode: "hasuradb",
|
||||
urlPrefix: "/console"
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.mainContent {
|
||||
display: 'none';
|
||||
opacity: 0;
|
||||
transition: opacity .20s linear;
|
||||
}
|
||||
.mainContent.show {
|
||||
display: 'block';
|
||||
opacity: 1;
|
||||
transition: opacity .20s linear;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="loading">
|
||||
<div class="page-loading" style="
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: sans-serif;
|
||||
justify-content: center;
|
||||
">
|
||||
<span class="" style="
|
||||
font-size: 2em;
|
||||
margin-top: -3em;
|
||||
color: #848484;
|
||||
">
|
||||
Loading...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="mainContent"></div>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
||||
<link rel="stylesheet" href="https://storage.googleapis.com/hasura-graphql-engine/console/1.0-dev/main.css" charset="UTF-8"/>
|
||||
<script src="https://storage.googleapis.com/hasura-graphql-engine/console/1.0-dev/vendor.js" charset="UTF-8"></script>
|
||||
<script src="https://storage.googleapis.com/hasura-graphql-engine/console/1.0-dev/main.js" charset="UTF-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,449 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
|
||||
<title>Hi! Your GraphQL endpoint on Postgres is ready. </title>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: octicons-anchor;
|
||||
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
max-width: 790px;
|
||||
margin: 0 auto;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.markdown-body a:active,
|
||||
.markdown-body a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.markdown-body code,
|
||||
.markdown-body kbd,
|
||||
.markdown-body pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.markdown-body input[type="checkbox"] {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.markdown-body td,
|
||||
.markdown-body th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body * {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
color: #4183c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body a:hover,
|
||||
.markdown-body a:focus,
|
||||
.markdown-body a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: 0;
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.markdown-body hr:before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body hr:after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 16px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.markdown-body h1 .octicon-link,
|
||||
.markdown-body h2 .octicon-link,
|
||||
.markdown-body h3 .octicon-link,
|
||||
.markdown-body h4 .octicon-link,
|
||||
.markdown-body h5 .octicon-link,
|
||||
.markdown-body h6 .octicon-link {
|
||||
display: none;
|
||||
color: #000;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor,
|
||||
.markdown-body h2:hover .anchor,
|
||||
.markdown-body h3:hover .anchor,
|
||||
.markdown-body h4:hover .anchor,
|
||||
.markdown-body h5:hover .anchor,
|
||||
.markdown-body h6:hover .anchor {
|
||||
height: 1em;
|
||||
padding-left: 8px;
|
||||
margin-left: -30px;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link,
|
||||
.markdown-body h2:hover .anchor .octicon-link,
|
||||
.markdown-body h3:hover .anchor .octicon-link,
|
||||
.markdown-body h4:hover .anchor .octicon-link,
|
||||
.markdown-body h5:hover .anchor .octicon-link,
|
||||
.markdown-body h6:hover .anchor .octicon-link {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 2.25em;
|
||||
line-height: 1.2;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 1.75em;
|
||||
line-height: 1.225;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.43;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 1em;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.markdown-body pre>code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body .highlight {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre,
|
||||
.markdown-body pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.markdown-body pre code {
|
||||
display: inline;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: initial;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body pre code:before,
|
||||
.markdown-body pre code:after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markdown-body ul,
|
||||
.markdown-body ol {
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ul ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.markdown-body ul ul ol,
|
||||
.markdown-body ul ol ol,
|
||||
.markdown-body ol ul ol,
|
||||
.markdown-body ol ol ol {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
|
||||
.markdown-body ul,
|
||||
.markdown-body ol,
|
||||
.markdown-body ul,
|
||||
.markdown-body ol {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.markdown-body ul ul,
|
||||
.markdown-body ul ol,
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ol ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body li>p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.hljs-variable {
|
||||
color: #008080;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.copy-div {
|
||||
position: relative;
|
||||
}
|
||||
.copy {
|
||||
position: absolute;
|
||||
top: calc(50% - 14px);
|
||||
right: 20px;
|
||||
cursor: pointer;
|
||||
background: #fff !important;
|
||||
padding: 5px 10px;
|
||||
font-size: 0.7em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
var curUrl = window.location.href;
|
||||
document.getElementById('init').innerHTML = `hasura init --directory my-project --endpoint ${curUrl}`;
|
||||
};
|
||||
var copyElements = ['code-install-copy', 'code-console-copy', 'init-copy'];
|
||||
function changeCopyButtonText(id) {
|
||||
copyElements.forEach(function (element) {
|
||||
if (element !== id){
|
||||
document.getElementById(element).innerHTML = 'Copy';
|
||||
} else {
|
||||
document.getElementById(element).innerHTML = 'Copied';
|
||||
}
|
||||
});
|
||||
}
|
||||
function code_console_copy_copied() {
|
||||
changeCopyButtonText('code-console-copy');
|
||||
};
|
||||
function code_install_copy_copied() {
|
||||
changeCopyButtonText('code-install-copy');
|
||||
};
|
||||
function init_copy_copied() {
|
||||
changeCopyButtonText('init-copy');
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<article class="markdown-body">
|
||||
<h2 id="hi!--your-graphql-endpoint-on-postgres-is-ready.-"><a class="header-link" href="#hi!--your-graphql-endpoint-on-postgres-is-ready.-"></a>Hi! Your GraphQL endpoint on Postgres is ready. </h2>
|
||||
<p>Now, start building your schema and exploring your GraphQL APIs:</p>
|
||||
<h4 id="1.-install-the-hasura-cli">Step 1: Install the Hasura CLI</h4>
|
||||
<h5 id="mac"><a class="header-link" href="#mac"></a>Mac / Linux</h5>
|
||||
<div class="copy-div">
|
||||
<pre class="hljs" id="code-install-cli">curl -L https://cli.hasura.io/install.sh | bash</pre>
|
||||
<a class="copy" data-clipboard-target="#code-install-cli" onclick="code_install_copy_copied()" id="code-install-copy">Copy</a>
|
||||
</div>
|
||||
<h5 id="linux">Windows</h5>
|
||||
<ul class="list">
|
||||
<li>Download the hasura installer for <a href="https://cli.hasura.io/install/windows-amd64">64-bit</a> or <a href="https://cli.hasura.io/install/windows-386">32-bit</a>.</li>
|
||||
<li>Run the hasura command in your shell (recommended: <a href="https://git-scm.com/download/win">git-bash</a>).</li>
|
||||
</ul>
|
||||
<h4 id="2.-initialize-a-project">Step 2: Initialize a project</h4>
|
||||
<div class="copy-div">
|
||||
<pre class="hljs" id="init"></pre>
|
||||
<a class="copy" data-clipboard-target="#init" onclick="init_copy_copied()" id="init-copy">Copy</a>
|
||||
</div>
|
||||
<h4 id="3.-open-the-hasura-console">Step 3: Open the Hasura Console</h4>
|
||||
<div class="copy-div">
|
||||
<pre class="hljs" id="code-console">cd my-project && hasura console</pre>
|
||||
<a class="copy" data-clipboard-target="#code-console" onclick="code_console_copy_copied()" id="code-console-copy">Copy</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
|
||||
<script>
|
||||
new ClipboardJS('.copy');
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -235,7 +235,7 @@ raven_app rlogger pool =
|
||||
do
|
||||
_ <- liftIO $ runExceptT $ Q.runTx pool defTxMode resetStateTx
|
||||
let corsCfg = CorsConfig "*" True -- cors is disabled
|
||||
spockAsApp $ spockT id $ app Q.Serializable Nothing rlogger pool AMNoAuth corsCfg -- no access key and no webhook
|
||||
spockAsApp $ spockT id $ app Q.Serializable Nothing rlogger pool AMNoAuth corsCfg True -- no access key and no webhook
|
||||
|
||||
main :: IO ()
|
||||
main = withStdoutLogger ravenLogGen $ \rlogger -> do
|
||||
|
||||
Reference in New Issue
Block a user