Comments (2)
Here's a documented plugin for this; let me know if you have any questions. Don't close this issue because we need to put this somewhere on the site.
// Author: Benjie Gillam
// License: https://benjie.mit-license.org/
//
// This is a documentation example, you will need to edit it to make it useful.
// Instructions on running this plugin are at the bottom.
// This function is the one that would perform sanitisation (writing actual
// sanitisation is left as an exercise to the reader)
function sanitize(html) {
return html.toUpperCase();
}
// Export our plugin function (it can be async if you want)
module.exports = /* async */ function SanitizeHTMLTypePlugin(builder) {
// Builder is an instance of SchemaBuilder:
//
// https://www.graphile.org/graphile-build/schema-builder/
//////////////////////////////////////////////////////////////////////////////
// Here we're hooking the init event; this event occurs after the `build`
// object is finalised, but before we start building our schema - it's the
// perfect time to hook up additional types.
//
// 'init' is an a-typical hook in that the first argument is meaningless (but
// you should still return it at the end of the hook).
//
// Note all hooks in graphile-build must be synchronous; any async work must be done above here.
builder.hook('init', (_, build) => {
// The `build` object is an instance of Build: https://www.graphile.org/graphile-build/build-object/
// graphile-build-pg adds a bunch of additional helpers to this object:
const {
pgIntrospectionResultsByKind, // From PgIntrospectionPlugin
pgRegisterGqlTypeByTypeId, // From PgTypesPlugin
pgRegisterGqlInputTypeByTypeId, // From PgTypesPlugin
pg2GqlMapper, // From PgTypesPlugin
pgSql: sql, // From PgBasicsPlugin, this is equivalent to `require('pg-sql2')` but avoids multiple-module conflicts
graphql, // Equivalent to `require('graphql')` but avoids multiple-module conflicts
} = build;
const { GraphQLString } = graphql;
// First we find the type that we care about. In this case we've done
//
// CREATE DOMAIN html AS text;
// or
// CREATE DOMAIN public.html AS text;
//
// so we are looking for the 'html' type in the 'public' schema (namespace).
const htmlDomain = pgIntrospectionResultsByKind.type.find(type => type.name === 'html' && type.namespaceName === 'public');
// If this type exists, then...
if (htmlDomain) {
// Register the *output* type for this type, we just want to use the `String` type
pgRegisterGqlTypeByTypeId(htmlDomain.id, () => GraphQLString);
// Register the *input* type for this type, again we'll use `String`
pgRegisterGqlInputTypeByTypeId(htmlDomain.id, () => GraphQLString);
// The pg2GqlMapper is responsible for translating things from PostgreSQL
// into GraphQL and back again.
pg2GqlMapper[htmlDomain.id] = {
// From Postgres to GraphQL: we simply take the string from postgres
// and sanitise it and return the resulting string to GraphQL.
map: value => sanitize(value),
// From GraphQL to SQL: we must construct an SQL fragment that can be
// interpolated into larger SQL queries (e.g. as the argument to a
// function or the input value for a CREATE/UPDATE mutation). Graphile
// uses the pg-sql2 module for this purpose, you can find the docs
// here:
//
// https://github.com/graphile/pg-sql2/blob/master/README.md
//
// We're going to take the value (string) the client gave us, stick it
// through the sanitise function, then pass it into SQL using
// `sql.value` to avoid SQL injection and being sure to cast it to our
// HTML type. Note that if you miss the `sql.value(...)` pg-sql2 will
// throw an error, so you don't have to worry about accidental SQL
// injection - just never use `sql.raw`!
unmap: value => sql.fragment`(${sql.value(sanitize(value))}::public.html)`,
};
}
// All hooks in graphile-build must return something; normally it's an
// augmented form of the thing that was passed as the first argument. We
// don't manipuate _ at all so we can simply return it.
return _;
});
}
/*
You can test this plugin by saving it to a file 'plugin.js', then executing the
following:
# Create a database to test against
createdb sanitise-html
# Seed the database with our domain, table and some data
psql -1X sanitise-html <<SQL
CREATE DOMAIN html AS text;
CREATE TABLE a (id SERIAL PRIMARY KEY, t TEXT, h HTML);
INSERT INTO a (t, h) VALUES ('AaAaAa', 'BbBbBb');
SQL
# Run PostGraphile
postgraphile --append-plugins `pwd`/plugin.js -c postgres:///sanitise-html
Here's a GraphQL query for selecting the data:
{
allAs {
nodes {
id
t
h
}
}
}
And one for updating the data:
mutation {
updateAById(
input: {
id: 1
aPatch: {
t: "tttt_TTTT_tttt"
h: "hhhh_HHHH_hhhh"
}
}
) {
a {
id
t
h
}
}
}
*/
from graphile.github.io.
Closed in #141
from graphile.github.io.
Related Issues (20)
- JWT refresh tokens
- What do you think about add "Postgraphile vs Prisma" in ยซ FAQ section ยป ? HOT 2
- Add to docs: PostGraphile supports any authentication that Node supports. HOT 2
- Firebase auth HOT 5
- Add React-Admin Postgraphile data-providers in Postgraphile documentation? HOT 5
- _FILE environment variable support for Docker Secrets HOT 3
- Recipe suggestion for calling postgres function from application layer HOT 2
- Improving --host 0.0.0.0 Documentation HOT 1
- Document How to Run in Azure VM HOT 1
- Inconsistent plugins development documentation HOT 10
- Style the details tag so that it's more obvious
- Example of changing from simple subscriptions to (equivalent) custom subscriptions
- Plugin example: setting the GraphQL type to use for a given PostgreSQL type
- Postgraphile Sandbox/Playground HOT 2
- Support: example of a more complicated subscription? (e.g. chat messages) HOT 1
- [Solved] Error: "Prepared statement ... already exists" when repeating query HOT 2
- bug: autodeploy not working HOT 1
- Add Database Function Restriction to Docs HOT 1
- Recipe: translate range types to/from Postgres' format instead of the object version
- Hooks filtering out interface child types from `makeExtendSchema` HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphile.github.io.