Skip to content

Commit

Permalink
alpha.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mattbretl committed Mar 16, 2018
1 parent 678298b commit 6d9016b
Show file tree
Hide file tree
Showing 8 changed files with 3,538 additions and 1 deletion.
41 changes: 41 additions & 0 deletions .eslintrc.js
@@ -0,0 +1,41 @@
module.exports = {
parserOptions: {
sourceType: "module",
},
extends: ["eslint:recommended", "prettier"],
plugins: ["prettier"],
env: {
node: true,
es6: true,
},
rules: {
"prettier/prettier": [
"error",
{
trailingComma: "es5",
},
],
"comma-dangle": [
2,
{
arrays: "always-multiline",
objects: "always-multiline",
imports: "always-multiline",
exports: "always-multiline",
functions: "never",
},
],
"no-confusing-arrow": 0,
"no-else-return": 0,
"no-underscore-dangle": 0,
"no-unused-vars": [
2,
{
argsIgnorePattern: "^_",
},
],
"no-restricted-syntax": 0,
"no-await-in-loop": 0,
camelcase: 0,
},
};
1 change: 1 addition & 0 deletions .gitattributes
@@ -0,0 +1 @@
* text=auto
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
76 changes: 75 additions & 1 deletion README.md
@@ -1,2 +1,76 @@
[![Package on npm](https://img.shields.io/npm/v/postgraphile-plugin-derived-field.svg)](https://www.npmjs.com/package/postgraphile-plugin-derived-field)

# postgraphile-plugin-derived-field
Add derived fields in PostGraphile
This plugin adds derived fields in PostGraphile v4.

> **Note:** This plugin targets the beta release of PostGraphile v4.
## Getting Started

``` js
const express = require("express");
const { postgraphile } = require("postgraphile");
const PostGraphileDerivedFieldPlugin = require("postgraphile-plugin-derived-field");

const app = express();

const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const bucket = "postgraphile-plugin-test";

app.use(
postgraphile(pgConfig, schema, {
graphiql: true,
appendPlugins: [PostGraphileDerivedFieldPlugin],
graphileBuildOptions: {
derivedFieldDefinitions: [
{
identifiers: ["my_schema.my_table.my_column"],
inflect: (fieldName) => `${fieldName}Derived`,
resolve: (val) => `Value derived from ${val}`
}
]
}
})
);

app.listen(5000);
```

## Examples

<details>

<summary>Generate pre-signed URLs for client-side S3 GET requests</summary>

``` js
const express = require("express");
const { postgraphile } = require("postgraphile");
const PostGraphileDerivedFieldPlugin = require("postgraphile-plugin-derived-field");

const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const bucket = "postgraphile-plugin-test";

const app = express();

app.use(
postgraphile(pgConfig, schema, {
graphiql: true,
appendPlugins: [PostGraphileDerivedFieldPlugin],
graphileBuildOptions: {
derivedFieldDefinitions: [
{
identifiers: ["my_schema.my_table.my_column"],
inflect: (fieldName) => `${fieldName}Url`,
resolve: (val) => s3.getSignedUrl('getObject', {Bucket: bucket, Key: val, Expires: 900})
}
]
}
})
);

app.listen(5000);
```

</details>
3 changes: 3 additions & 0 deletions index.js
@@ -0,0 +1,3 @@
module.exports = function PostGraphileDerivedFieldPlugin(builder, options) {
require("./src/DerivedFieldPlugin.js")(builder, options);
};
39 changes: 39 additions & 0 deletions package.json
@@ -0,0 +1,39 @@
{
"name": "postgraphile-plugin-derived-field",
"version": "1.0.0-alpha.0",
"description": "Add derived fields in PostGraphile",
"main": "index.js",
"scripts": {
"test": "scripts/test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mattbretl/postgraphile-plugin-derived-field.git"
},
"author": "Matt Bretl",
"license": "MIT",
"bugs": {
"url": "https://github.com/mattbretl/postgraphile-plugin-derived-field/issues"
},
"dependencies": {},
"peerDependencies": {
"postgraphile": "^4.0.0-beta.0"
},
"devDependencies": {
"eslint": "^4.0.0",
"eslint-config-prettier": "2.3.0",
"eslint-plugin-jest": "^20.0.3",
"eslint-plugin-prettier": "^2.1.2",
"graphql": "^0.10.5",
"jest": "^20.0.4",
"pg": ">=6.1.0 <8",
"postgraphile-core": "^4.0.0-beta.0",
"prettier": "^1.4.4"
},
"jest": {
"testRegex": "__tests__/.*\\.test\\.js$"
},
"files": [
"src"
]
}
93 changes: 93 additions & 0 deletions src/DerivedFieldPlugin.js
@@ -0,0 +1,93 @@
function DerivedFieldPlugin(
builder,
{ pgInflection: inflection, derivedFieldDefinitions }
) {
builder.hook("GraphQLObjectType:fields", (fields, build, context) => {
const {
extend,
pgIntrospectionResultsByKind: introspectionResultsByKind,
graphql: { GraphQLString },
pgColumnFilter,
fieldDataGeneratorsByFieldNameByType,
} = build;
const {
scope: { pgIntrospection: table, isPgRowType },
fieldWithHooks,
Self,
} = context;

if (
!isPgRowType ||
!table ||
table.kind !== "class" ||
derivedFieldDefinitions == null
) {
return fields;
}

const tableType = introspectionResultsByKind.type.filter(
type =>
type.type === "c" &&
type.namespaceId === table.namespaceId &&
type.classId === table.id
)[0];
if (!tableType) {
throw new Error("Could not determine the type for this table");
}

const derivedFields = introspectionResultsByKind.attribute
.filter(attr => attr.classId === table.id)
.filter(attr => pgColumnFilter(attr, build, context))
.reduce((memo, attr) => {
for (let def of derivedFieldDefinitions) {
if (
def.identifiers.includes(
`${table.namespaceName}.${table.name}.${attr.name}`
)
) {
const fieldName = inflection.column(
attr.name,
table.name,
table.namespaceName
);
const derivedFieldName = def.inflect(fieldName);
if (memo[derivedFieldName]) {
throw new Error(
`Derived field '${derivedFieldName}' conflicts with existing GraphQL field`
);
}
const field = fields[fieldName];
const { resolve: oldResolve } = field;
memo[derivedFieldName] = fieldWithHooks(
derivedFieldName,
({ addDataGenerator }) => {
const generatorsByField = fieldDataGeneratorsByFieldNameByType.get(
Self
);
generatorsByField[fieldName].forEach(g => {
addDataGenerator(g);
});
return {
type: def.returnType || GraphQLString,
resolve: (...resolveParams) => {
const val = oldResolve(...resolveParams);
return def.resolve(val);
},
};
},
{ pgFieldIntrospection: attr }
);
}
}
return memo;
}, {});

return extend(
fields,
derivedFields,
`Adding derived field to '${Self.name}'`
);
});
}

module.exports = DerivedFieldPlugin;

0 comments on commit 6d9016b

Please sign in to comment.