Skip to content

Commit

Permalink
fix: missing files in wasm example
Browse files Browse the repository at this point in the history
  • Loading branch information
dosco committed Dec 16, 2022
1 parent 93b300a commit 149b7aa
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 44 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ release
node_modules
bin
./package-lock.json
config
slim.report.json


1 change: 1 addition & 0 deletions core/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config
128 changes: 128 additions & 0 deletions examples/nodejs/config/dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# When production mode is 'true' only queries
# from the allow list are permitted.
production: false

# Secret key for general encryption operations like
# encrypting the cursor data
secret_key: supercalifajalistics

# Subscriptions poll the database to query for updates
# this sets the duration (in seconds) between requests.
# Defaults to 5 seconds
subs_poll_every_seconds: 5

# Default limit value to be used on queries and as the max
# limit on all queries where a limit is defined as a query variable.
# Defaults to 20
default_limit: 20

# Disables all aggregation functions like count, sum, etc
# disable_agg_functions: false

# Disables all functions like count, length, etc
# disable_functions: false

# Enables using camel case terms in GraphQL which are converted
# to snake case in SQL
# enable_camelcase: false

# Set session variable "user.id" to the user id
# Enable this if you need the user id in triggers, etc
# Note: This will not work with subscriptions
set_user_id: false

# DefaultBlock ensures that in anonymous mode (role 'anon') all tables
# are blocked from queries and mutations. To open access to tables in
# anonymous mode they have to be added to the 'anon' role config.
default_block: false

# Define additional variables here to be used with filters
# Variables used require a type suffix eg. $user_id:bigint
variables:
#admin_account_id: "5"
admin_account_id: "sql:select id from users where admin = true limit 1"

# Define variables set to values extracted from http headers
header_variables:
remote_ip: "X-Forwarded-For"

# Field and table names that you wish to block
blocklist:
- ar_internal_metadata
- schema_migrations
- secret
- password
- encrypted
- token

# resolvers:
# - name: payments
# type: remote_api
# table: customers
# column: stripe_id
# json_path: data
# debug: false
# url: http://payments/payments/$id
# pass_headers:
# - cookie
# set_headers:
# - name: Host
# value: 0.0.0.0
# # - name: Authorization
# # value: Bearer <stripe_api_key>

tables:
- # You can create new fields that have a
# real db table backing them
name: me
table: users

- name: users
order_by:
new_users: ["created_at desc", "id asc"]
id: ["id asc"]

# Variables used require a type suffix eg. $user_id:bigint
#roles_query: "SELECT * FROM users WHERE id = $user_id:bigint"

roles:
# if `auth.type` is set to a valid auth type then
# all tables are blocked for the anon role unless
# added to the role like below.
# - name: anon
# tables:
# - name: users
# query:
# limit: 10

- name: user
tables:
- name: me
query:
filters: ["{ id: { _eq: $user_id } }"]

# - name: products
# query:
# limit: 50
# filters: ["{ user_id: { eq: $user_id } }"]
# disable_functions: false

# insert:
# filters: ["{ user_id: { eq: $user_id } }"]
# presets:
# - user_id: "$user_id"
# - created_at: "now"

# update:
# filters: ["{ user_id: { eq: $user_id } }"]
# presets:
# - updated_at: "now"

# delete:
# block: true

# - name: admin
# match: id = 1000
# tables:
# - name: users
# filters: []
21 changes: 21 additions & 0 deletions examples/nodejs/config/prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Inherit config from this other config file
# so I only need to overwrite some values
inherits: dev

# When production mode is 'true' only queries
# from the allow list are permitted.
production: true

# Secret key for general encryption operations like
# encrypting the cursor data
secret_key: supercalifajalistics

# Subscriptions poll the database to query for updates
# this sets the duration (in seconds) between requests.
# Defaults to 5 seconds
subs_poll_every_seconds: 5

# Default limit value to be used on queries and as the max
# limit on all queries where a limit is defined as a query variable.
# Defaults to 20
default_limit: 20
60 changes: 39 additions & 21 deletions examples/nodejs/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import graphjin from "graphjin";
import express from "express";
import http from "http";
// import express from "express";
// import http from "http";
import pg from "pg"

const { Client } = pg
Expand All @@ -17,27 +17,45 @@ await db.connect()
// config can either be a file (eg. `dev.yml`) or an object
// const config = { production: true, default_limit: 50 };

var gj = await graphjin("./config", "dev.yml", db);
var app = express();
var server = http.createServer(app);
// var app = express();
// var server = http.createServer(app);

const res1 = await gj.subscribe(
"subscription getUpdatedUser { users(id: $userID) { id email } }",
null,
{ userID: 2 })
// const res1 = await gj.subscribe(
// "subscription getUpdatedUser { users(id: $userID) { id email } }",
// null,
// { userID: 2 })

res1.data(function(res) {
console.log(">", res.data())
})
// res1.data(function(res) {
// console.log(">", res.data())
// })

app.get('/', async function(req, resp) {
const res2 = await gj.query(
"query getUser { users(id: $id) { id email } }",
{ id: 1 },
{ userID: 1 })
var gj = await graphjin("./config", "dev.yml", db);

resp.send(res2.data());
});

server.listen(3000);
console.log('Express server started on port %s', server.address().port);
const q = `
query test {
organization_users (where: { organization_id: $id} ) {
role
users {
id
email
}
}
}
`

for (let i = 0; i < 10000;i++) {
const res = await gj.query(q, { id: 1 })
console.log(i, JSON.stringify(res.data()))
// console.log(res.sql())
}
process.exit(0);

// app.get('/', async function(req, resp) {


// resp.send(res2.data());
// });

// server.listen(3000);
// console.log('Express server started on port %s', server.address().port);
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "graphjin",
"version": "2.0.4",
"description": "GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.",
"version": "2.0.5",
"description": "GraphJin - Build APIs in 5 minutes with GraphQL",
"type": "module",
"main": "wasm/js/graphjin.js",
"files": [
Expand Down
42 changes: 24 additions & 18 deletions wasm/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,45 @@ type queryArgs struct {
}

func newQueryArgs(args []js.Value) (qa queryArgs, jsErr js.Value) {
if len(args) < 2 {
err := errors.New("required arguments: query, variables")
if len(args) < 1 {
err := errors.New("required arguments: query")
return qa, toJSError(err)
}
query := args[0]

if query.Type() != js.TypeString || query.String() == "" {
return qa, toJSError(errors.New("query argument missing"))
}

qa.query = query.String()

return processQueryArgs(qa, args)
}

func newQueryByNameArgs(args []js.Value) (qa queryArgs, jsErr js.Value) {
if len(args) < 2 {
err := errors.New("required arguments: name, variables")
if len(args) < 1 {
err := errors.New("required arguments: name")
return qa, toJSError(err)
}
name := args[0]

if name.Type() != js.TypeString || name.String() == "" {
return qa, toJSError(errors.New("query argument missing"))
}

qa.query = name.String()

return processQueryArgs(qa, args)
}

func processQueryArgs(qa queryArgs, args []js.Value) (queryArgs, js.Value) {
var err error
if len(args) == 1 {
return qa, js.Null()
}
vars := args[1]
opts := args[2]

if vars.Type() != js.TypeObject &&
vars.Type() != js.TypeNull && vars.Type() != js.TypeUndefined {
err = errors.New("variables argument can only be a string or null")
}

if opts.Type() != js.TypeObject &&
opts.Type() != js.TypeNull && opts.Type() != js.TypeUndefined {
err = errors.New("options argument can only be a object or null")
}

if err != nil {
vars.Type() != js.TypeNull &&
vars.Type() != js.TypeUndefined {
err := errors.New("variables argument can only be a string or null")
return qa, toJSError(err)
}

Expand All @@ -68,6 +62,18 @@ func processQueryArgs(qa queryArgs, args []js.Value) (queryArgs, js.Value) {
qa.vars = json.RawMessage(val.String())
}

if len(args) == 2 {
return qa, js.Null()
}
opts := args[2]

if opts.Type() != js.TypeObject &&
opts.Type() != js.TypeNull &&
opts.Type() != js.TypeUndefined {
err := errors.New("options argument can only be a object or null")
return qa, toJSError(err)
}

if v := opts.Get("userID"); v.Type() == js.TypeString || v.Type() == js.TypeNumber {
qa.userID = optVal(v)
}
Expand Down
Loading

1 comment on commit 149b7aa

@vercel
Copy link

@vercel vercel bot commented on 149b7aa Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.