mirror of
https://github.com/Ratstail91/sineQL.git
synced 2025-11-29 02:34:28 +11:00
Adjusted handler API
This commit is contained in:
53
test-server-books/database.js
Normal file
53
test-server-books/database.js
Normal file
@@ -0,0 +1,53 @@
|
||||
//the authors
|
||||
let authors = [
|
||||
{
|
||||
name: 'J.K. Roaring',
|
||||
books: [
|
||||
{ title: 'The Philosepher\'s Kidney Stone' },
|
||||
{ title: 'The Chamber Pot of Secrets' },
|
||||
{ title: 'The Prisoner of Aunt Kazban' },
|
||||
{ title: 'The Goblet of the Fire Cocktail' },
|
||||
{ title: 'The Order for Kleenex' },
|
||||
{ title: 'The Half-Priced Pharmacy' },
|
||||
{ title: 'Yeah, I Got Nothing' },
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Kenneth Grahame',
|
||||
books: [
|
||||
{ title: 'The Wind in the Willows', published: '1 April 1908' }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Kayne Ruse',
|
||||
books: [
|
||||
{ title: 'alpha', published: "1" },
|
||||
{ title: 'beta', published: "2" },
|
||||
{ title: 'gamma', published: "3" },
|
||||
{ title: 'delta', published: "4" },
|
||||
{ title: 'epsilon', published: "5" },
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
//insert the authors into the books (relationship)
|
||||
authors = authors.map(a => {
|
||||
a.books = a.books.map(b => {
|
||||
b.authors = [a];
|
||||
return b;
|
||||
});
|
||||
return a;
|
||||
});
|
||||
|
||||
//get the books array
|
||||
let books = [];
|
||||
|
||||
authors.forEach(a => books = books.concat(a.books));
|
||||
|
||||
//the fake database
|
||||
module.exports = {
|
||||
authors,
|
||||
books,
|
||||
};
|
||||
180
test-server-books/handler.js
Normal file
180
test-server-books/handler.js
Normal file
@@ -0,0 +1,180 @@
|
||||
/* DOCS: parameter types
|
||||
parent: Type | null
|
||||
scalars: [{ typeName: String, name: String, filter: any | null }, ...]
|
||||
matching: Boolean
|
||||
*/
|
||||
|
||||
const database = require('./database.js');
|
||||
|
||||
//the handler routines
|
||||
const handler = {
|
||||
//type queries
|
||||
Author: (parent, scalars, matching) => {
|
||||
console.log("Author", parent ? parent.context : null);
|
||||
|
||||
let authors;
|
||||
|
||||
//check parentage
|
||||
if (parent) {
|
||||
//find the author(s) of the parent Book object
|
||||
authors = database.authors.filter(author => author.books.some(b => b.title == parent.context.title));
|
||||
} else {
|
||||
authors = database.authors;
|
||||
}
|
||||
|
||||
//I am being matched (if true, ALL present scalars will have a filter field)
|
||||
if (matching) {
|
||||
//check every scalar to every author - a single false match is a miss on that author
|
||||
authors = authors.filter(author => {
|
||||
return scalars.every(scalar => {
|
||||
//handle each type of scalar
|
||||
switch (scalar.typeName) {
|
||||
case 'String':
|
||||
case 'Integer':
|
||||
case 'Float':
|
||||
case 'Boolean':
|
||||
return author[scalar.name] == scalar.filter; //dumb comparison for now
|
||||
|
||||
//custom handling
|
||||
//NOTE: Only books used the `Date` scalar
|
||||
|
||||
default:
|
||||
throw `Unknown scalar typeName in handler: ${scalar.typeName} (${scalar.name})`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//if there are no authors left, then the book's filters missed matches
|
||||
if (authors.length == 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
//scalars are being matched on their own
|
||||
if (scalars.some(s => s.filter)) {
|
||||
//check every scalar to every author - a single match is a hit
|
||||
authors = authors.filter(author => {
|
||||
return scalars.some(scalar => {
|
||||
//handle each type of scalar
|
||||
switch (scalar.typeName) {
|
||||
case 'String':
|
||||
case 'Integer':
|
||||
case 'Float':
|
||||
case 'Boolean':
|
||||
return author[scalar.name] == scalar.filter; //dumb comparison for now
|
||||
|
||||
//custom handling
|
||||
//NOTE: Only books used the `Date` scalar
|
||||
|
||||
default:
|
||||
throw `Unknown scalar typeName in handler: ${scalar.typeName} (${scalar.name})`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//if there are no authors left, then the book's filters missed matches
|
||||
if (authors.length == 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
//process (filter out unwanted fields) and return the array of authors
|
||||
return authors.map(author => {
|
||||
let ret = {};
|
||||
|
||||
//that's a big O(damn)
|
||||
scalars.forEach(scalar => {
|
||||
ret[scalar.name] = author[scalar.name];
|
||||
});
|
||||
|
||||
return ret;
|
||||
});
|
||||
},
|
||||
|
||||
Book: (parent, scalars, matching) => {
|
||||
console.log("Book", parent ? parent.context : null);
|
||||
|
||||
let books;
|
||||
|
||||
//check parentage
|
||||
if (parent) {
|
||||
//find the books of the parent author object
|
||||
books = database.books.filter(book => book.authors.some(a => a.name == parent.context.name));
|
||||
} else {
|
||||
books = database.books;
|
||||
}
|
||||
|
||||
//I am being matched (if true, ALL present scalars will have a filter field)
|
||||
if (matching) {
|
||||
//check every scalar to every book - a single false match is a miss on that book
|
||||
books = books.filter(book => {
|
||||
return scalars.every(scalar => {
|
||||
//handle each type of scalar
|
||||
switch (scalar.typeName) {
|
||||
case 'String':
|
||||
case 'Integer':
|
||||
case 'Float':
|
||||
case 'Boolean':
|
||||
return book[scalar.name] == scalar.filter; //dumb comparison for now
|
||||
|
||||
//custom handling
|
||||
case 'Date':
|
||||
return book[scalar.name] == scalar.filter; //could have a more complex comparator function, like date-ranges
|
||||
|
||||
default:
|
||||
throw `Unknown scalar typeName in handler: ${scalar.typeName} (${scalar.name})`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
//if there are no books left, then the authos's filters missed matches
|
||||
if (books.length == 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
//scalars are being matched on their own
|
||||
if (scalars.some(s => s.filter)) {
|
||||
//check every scalar to every author - a single match is a hit
|
||||
books = books.filter(author => {
|
||||
return scalars.some(scalar => {
|
||||
//handle each type of scalar
|
||||
switch (scalar.typeName) {
|
||||
case 'String':
|
||||
case 'Integer':
|
||||
case 'Float':
|
||||
case 'Boolean':
|
||||
return author[scalar.name] == scalar.filter; //dumb comparison for now
|
||||
|
||||
//custom handling
|
||||
//NOTE: Only books used the `Date` scalar
|
||||
|
||||
default:
|
||||
throw `Unknown scalar typeName in handler: ${scalar.typeName} (${scalar.name})`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//if there are no authors left, then the book's filters missed matches
|
||||
if (books.length == 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
//process (filter out unwanted fields) and return the array of books
|
||||
return books.map(book => {
|
||||
let ret = {};
|
||||
|
||||
//that's a big O(damn)
|
||||
scalars.forEach(scalar => {
|
||||
ret[scalar.name] = book[scalar.name];
|
||||
});
|
||||
|
||||
return ret;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = handler;
|
||||
1807
test-server-books/package-lock.json
generated
Normal file
1807
test-server-books/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
test-server-books/package.json
Normal file
20
test-server-books/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "test-server",
|
||||
"version": "0.2.1",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "pm2 start server.js",
|
||||
"restart": "pm2 restart server.js",
|
||||
"stop": "pm2 stop server.js",
|
||||
"list": "pm2 list",
|
||||
"node": "node server.js"
|
||||
},
|
||||
"author": "Kayne Ruse",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"pm2": "^4.4.1"
|
||||
}
|
||||
}
|
||||
14
test-server-books/schema.js
Normal file
14
test-server-books/schema.js
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = `
|
||||
scalar Date
|
||||
|
||||
type Author {
|
||||
String name
|
||||
Book books
|
||||
}
|
||||
|
||||
type Book {
|
||||
String title
|
||||
Date published
|
||||
Author authors
|
||||
}
|
||||
`;
|
||||
27
test-server-books/server.js
Normal file
27
test-server-books/server.js
Normal file
@@ -0,0 +1,27 @@
|
||||
//express for testing
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(cors());
|
||||
app.use(bodyParser.text());
|
||||
|
||||
//test the library
|
||||
const schema = require('./schema.js');
|
||||
const handler = require('./handler.js');
|
||||
const sineQL = require('../source/index.js');
|
||||
|
||||
const sine = sineQL(schema, handler, { debug: false });
|
||||
|
||||
//open the end
|
||||
app.post('/sineql', async (req, res) => {
|
||||
const [code, result] = await sine(req.body);
|
||||
res.status(code).send(result);
|
||||
});
|
||||
|
||||
//startup
|
||||
app.listen(process.env.WEB_PORT || 3100, err => {
|
||||
console.log(`listening to *:${process.env.WEB_PORT || 3100}`);
|
||||
});
|
||||
Reference in New Issue
Block a user