graphile-build-pg
Advanced tools
Comparing version 0.1.0-alpha.41 to 4.0.0-alpha
@@ -1,13 +0,5 @@ | ||
// @flow | ||
// This script detects if you're running on Node v8 or above; if so it runs the | ||
// code directly, otherwise it falls back to the babel-compiled version | ||
/*:: | ||
// Trick flow into exporting the types | ||
export type * from './node8plus'; | ||
*/ | ||
const isNode8Plus = process.versions.node.match(/^([89]|[1-9][0-9]+)\./); | ||
// $FlowFixMe: ignore | ||
module.exports = isNode8Plus ? require("./node8plus") : require("./node7minus"); |
@@ -12,2 +12,6 @@ "use strict"; | ||
var _keys = require("babel-runtime/core-js/object/keys"); | ||
var _keys2 = _interopRequireDefault(_keys); | ||
var _pluralize = require("pluralize"); | ||
@@ -29,2 +33,21 @@ | ||
function preventEmptyResult(obj) { | ||
return (0, _keys2.default)(obj).reduce(function (memo, key) { | ||
var fn = obj[key]; | ||
memo[key] = function () { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
var result = fn.apply(memo, args); | ||
if (typeof result !== "string" || result.length === 0) { | ||
var stringifiedArgs = require("util").inspect(args); | ||
throw new Error(`Inflector for '${key}' returned '${String(result)}'; expected non-empty string\n` + `See: https://github.com/graphile/graphile-build/blob/master/packages/graphile-build-pg/src/inflections.js\n` + `Arguments passed to ${key}:\n${stringifiedArgs}`); | ||
} | ||
return result; | ||
}; | ||
return memo; | ||
}, {}); | ||
} | ||
var newInflector = exports.newInflector = function newInflector() { | ||
@@ -44,3 +67,3 @@ var overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; | ||
return (0, _assign2.default)({ | ||
return preventEmptyResult((0, _assign2.default)({ | ||
pluralize, | ||
@@ -59,8 +82,78 @@ argument(name, index) { | ||
}, | ||
enumName(value) { | ||
enumName(inValue) { | ||
var value = inValue; | ||
if (value === "") { | ||
return "_EMPTY_"; | ||
} | ||
var valueWithAsterisksReplaced = value.replace(/\*/g, "_ASTERISK_").replace(/^(_?)_+ASTERISK/, "$1ASTERISK").replace(/ASTERISK_(_?)_*$/, "ASTERISK$1"); | ||
return valueWithAsterisksReplaced; | ||
// Some enums use asterisks to signify wildcards - this might be for | ||
// the whole item, or prefixes/suffixes, or even in the middle. This | ||
// is provided on a best efforts basis, if it doesn't suit your | ||
// purposes then please pass a custom inflector as mentioned below. | ||
value = value.replace(/\*/g, "_ASTERISK_").replace(/^(_?)_+ASTERISK/, "$1ASTERISK").replace(/ASTERISK_(_?)_*$/, "ASTERISK$1"); | ||
// This is a best efforts replacement for common symbols that you | ||
// might find in enums. Generally we only support enums that are | ||
// alphanumeric, if these replacements don't work for you, you should | ||
// pass a custom inflector that replaces this `enumName` method | ||
// with one of your own chosing. | ||
value = { | ||
// SQL comparison operators | ||
">": "GREATER_THAN", | ||
">=": "GREATER_THAN_OR_EQUAL", | ||
"=": "EQUAL", | ||
"!=": "NOT_EQUAL", | ||
"<>": "DIFFERENT", | ||
"<=": "LESS_THAN_OR_EQUAL", | ||
"<": "LESS_THAN", | ||
// PostgreSQL LIKE shortcuts | ||
"~~": "LIKE", | ||
"~~*": "ILIKE", | ||
"!~~": "NOT_LIKE", | ||
"!~~*": "NOT_ILIKE", | ||
// '~' doesn't necessarily represent regexps, but the three | ||
// operators following it likely do, so we'll use the word TILDE | ||
// in all for consistency. | ||
"~": "TILDE", | ||
"~*": "TILDE_ASTERISK", | ||
"!~": "NOT_TILDE", | ||
"!~*": "NOT_TILDE_ASTERISK", | ||
// A number of other symbols where we're not sure of their | ||
// meaning. We give them common generic names so that they're | ||
// suitable for multiple purposes, e.g. favouring 'PLUS' over | ||
// 'ADDITION' and 'DOT' over 'FULL_STOP' | ||
"%": "PERCENT", | ||
"+": "PLUS", | ||
"-": "MINUS", | ||
"/": "SLASH", | ||
"\\": "BACKSLASH", | ||
_: "UNDERSCORE", | ||
"#": "POUND", | ||
"£": "STERLING", | ||
$: "DOLLAR", | ||
"&": "AMPERSAND", | ||
"@": "AT", | ||
"'": "APOSTROPHE", | ||
'"': "QUOTE", | ||
"`": "BACKTICK", | ||
":": "COLON", | ||
";": "SEMICOLON", | ||
"!": "EXCLAMATION_POINT", | ||
"?": "QUESTION_MARK", | ||
",": "COMMA", | ||
".": "DOT", | ||
"^": "CARET", | ||
"|": "BAR", | ||
"[": "OPEN_BRACKET", | ||
"]": "CLOSE_BRACKET", | ||
"(": "OPEN_PARENTHESIS", | ||
")": "CLOSE_PARENTHESIS", | ||
"{": "OPEN_BRACE", | ||
"}": "CLOSE_BRACE" | ||
}[value] || value; | ||
return value; | ||
}, | ||
@@ -203,3 +296,3 @@ enumType(name) { | ||
} | ||
}, overrides); | ||
}, overrides)); | ||
}; | ||
@@ -206,0 +299,0 @@ |
@@ -27,5 +27,15 @@ "use strict"; | ||
var OMIT = 0; | ||
var DEPRECATED = 1; | ||
var ONLY = 2; | ||
exports.default = function PgBackwardRelationPlugin(builder, _ref) { | ||
var inflection = _ref.pgInflection; | ||
var inflection = _ref.pgInflection, | ||
pgLegacyRelations = _ref.pgLegacyRelations; | ||
var legacyRelationMode = { | ||
only: ONLY, | ||
deprecated: DEPRECATED | ||
}[pgLegacyRelations] || OMIT; | ||
builder.hook("GraphQLObjectType:fields", function (fields, _ref2, _ref3) { | ||
@@ -69,2 +79,3 @@ var extend = _ref2.extend, | ||
var foreignTable = introspectionResultsByKind.classById[constraint.foreignClassId]; | ||
var foreignTableTypeName = inflection.tableType(foreignTable.name, foreignTable.namespace.name); | ||
var gqlForeignTableType = pgGetGqlTypeByTypeId(foreignTable.type.id); | ||
@@ -101,3 +112,9 @@ if (!gqlForeignTableType) { | ||
} | ||
var singleKey = keys.length === 1 ? keys[0] : null; | ||
var isUnique = !!(singleKey && introspectionResultsByKind.constraint.find(function (c) { | ||
return c.classId === singleKey.classId && c.keyAttributeNums.length === 1 && c.keyAttributeNums[0] === singleKey.num && (c.type === "p" || c.type === "u"); | ||
})); | ||
var isDeprecated = isUnique && legacyRelationMode === DEPRECATED; | ||
var simpleKeys = keys.map(function (k) { | ||
@@ -110,3 +127,5 @@ return { | ||
}); | ||
var fieldName = inflection.manyRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name); | ||
var manyRelationFieldName = inflection.manyRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name); | ||
var singleRelationFieldName = isUnique ? inflection.singleRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name) : null; | ||
var primaryKeyConstraint = introspectionResultsByKind.constraint.filter(function (con) { | ||
@@ -123,53 +142,100 @@ return con.classId === table.id; | ||
memo[fieldName] = fieldWithHooks(fieldName, function (_ref4) { | ||
var getDataFromParsedResolveInfoFragment = _ref4.getDataFromParsedResolveInfoFragment, | ||
addDataGenerator = _ref4.addDataGenerator; | ||
var shouldAddSingleRelation = isUnique && legacyRelationMode !== ONLY; | ||
addDataGenerator(function (parsedResolveInfoFragment) { | ||
return { | ||
pgQuery: function pgQuery(queryBuilder) { | ||
queryBuilder.select(function () { | ||
var resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ConnectionType); | ||
var tableAlias = sql.identifier((0, _symbol2.default)()); | ||
var foreignTableAlias = queryBuilder.getTableAlias(); | ||
var query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
withPagination: true, | ||
withPaginationAsFields: false | ||
}, function (innerQueryBuilder) { | ||
if (primaryKeys) { | ||
innerQueryBuilder.beforeLock("orderBy", function () { | ||
// append order by primary key to the list of orders | ||
if (!innerQueryBuilder.isOrderUnique(false)) { | ||
innerQueryBuilder.data.cursorPrefix = ["primary_key_asc"]; | ||
primaryKeys.forEach(function (key) { | ||
innerQueryBuilder.orderBy(sql.fragment`${innerQueryBuilder.getTableAlias()}.${sql.identifier(key.name)}`, true); | ||
}); | ||
innerQueryBuilder.setOrderIsUnique(); | ||
} | ||
var shouldAddManyRelation = !isUnique || legacyRelationMode === DEPRECATED || legacyRelationMode === ONLY; | ||
if (shouldAddSingleRelation) { | ||
memo[singleRelationFieldName] = fieldWithHooks(singleRelationFieldName, function (_ref4) { | ||
var getDataFromParsedResolveInfoFragment = _ref4.getDataFromParsedResolveInfoFragment, | ||
addDataGenerator = _ref4.addDataGenerator; | ||
addDataGenerator(function (parsedResolveInfoFragment) { | ||
return { | ||
pgQuery: function pgQuery(queryBuilder) { | ||
queryBuilder.select(function () { | ||
var resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, gqlTableType); | ||
var tableAlias = sql.identifier((0, _symbol2.default)()); | ||
var foreignTableAlias = queryBuilder.getTableAlias(); | ||
var query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
asJson: true, | ||
addNullCase: true, | ||
withPagination: false | ||
}, function (innerQueryBuilder) { | ||
keys.forEach(function (key, i) { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
} | ||
keys.forEach(function (key, i) { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
}); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
} | ||
}; | ||
}); | ||
return { | ||
description: `Reads a single \`${tableTypeName}\` that is related to this \`${foreignTableTypeName}\`.`, | ||
type: gqlTableType, | ||
args: {}, | ||
resolve: function resolve(data, _args, _context, resolveInfo) { | ||
var alias = getAliasFromResolveInfo(resolveInfo); | ||
return data[alias]; | ||
} | ||
}; | ||
}, { | ||
pgFieldIntrospection: table | ||
}); | ||
var ConnectionType = getTypeByName(inflection.connection(gqlTableType.name)); | ||
return { | ||
description: `Reads and enables pagination through a set of \`${tableTypeName}\`.`, | ||
type: new GraphQLNonNull(ConnectionType), | ||
args: {}, | ||
resolve: function resolve(data, _args, _context, resolveInfo) { | ||
var alias = getAliasFromResolveInfo(resolveInfo); | ||
return (0, _addStartEndCursor2.default)(data[alias]); | ||
} | ||
}; | ||
}, { | ||
isPgFieldConnection: true, | ||
pgFieldIntrospection: table | ||
}); | ||
} | ||
if (shouldAddManyRelation) { | ||
memo[manyRelationFieldName] = fieldWithHooks(manyRelationFieldName, function (_ref5) { | ||
var getDataFromParsedResolveInfoFragment = _ref5.getDataFromParsedResolveInfoFragment, | ||
addDataGenerator = _ref5.addDataGenerator; | ||
addDataGenerator(function (parsedResolveInfoFragment) { | ||
return { | ||
pgQuery: function pgQuery(queryBuilder) { | ||
queryBuilder.select(function () { | ||
var resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ConnectionType); | ||
var tableAlias = sql.identifier((0, _symbol2.default)()); | ||
var foreignTableAlias = queryBuilder.getTableAlias(); | ||
var query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
withPagination: true, | ||
withPaginationAsFields: false | ||
}, function (innerQueryBuilder) { | ||
if (primaryKeys) { | ||
innerQueryBuilder.beforeLock("orderBy", function () { | ||
// append order by primary key to the list of orders | ||
if (!innerQueryBuilder.isOrderUnique(false)) { | ||
innerQueryBuilder.data.cursorPrefix = ["primary_key_asc"]; | ||
primaryKeys.forEach(function (key) { | ||
innerQueryBuilder.orderBy(sql.fragment`${innerQueryBuilder.getTableAlias()}.${sql.identifier(key.name)}`, true); | ||
}); | ||
innerQueryBuilder.setOrderIsUnique(); | ||
} | ||
}); | ||
} | ||
keys.forEach(function (key, i) { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
}); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
} | ||
}; | ||
}); | ||
var ConnectionType = getTypeByName(inflection.connection(gqlTableType.name)); | ||
return { | ||
description: `Reads and enables pagination through a set of \`${tableTypeName}\`.`, | ||
type: new GraphQLNonNull(ConnectionType), | ||
args: {}, | ||
resolve: function resolve(data, _args, _context, resolveInfo) { | ||
var alias = getAliasFromResolveInfo(resolveInfo); | ||
return (0, _addStartEndCursor2.default)(data[alias]); | ||
}, | ||
deprecationReason: isDeprecated ? // $FlowFixMe | ||
`Please use ${singleRelationFieldName} instead` : undefined | ||
}; | ||
}, { | ||
isPgFieldConnection: true, | ||
pgFieldIntrospection: table | ||
}); | ||
} | ||
return memo; | ||
@@ -176,0 +242,0 @@ }, {}), `Adding backward relations for ${Self.name}`); |
@@ -509,3 +509,3 @@ "use strict"; | ||
} catch (e) { | ||
var error = new Error(`Error occurred when processing type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`); | ||
var error = new Error(`Error occurred when processing database type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`); | ||
// $FlowFixMe | ||
@@ -512,0 +512,0 @@ error.originalError = e; |
@@ -12,2 +12,6 @@ "use strict"; | ||
var _keys = require("babel-runtime/core-js/object/keys"); | ||
var _keys2 = _interopRequireDefault(_keys); | ||
var _pluralize = require("pluralize"); | ||
@@ -29,2 +33,17 @@ | ||
function preventEmptyResult(obj) { | ||
return (0, _keys2.default)(obj).reduce((memo, key) => { | ||
const fn = obj[key]; | ||
memo[key] = (...args) => { | ||
const result = fn.apply(memo, args); | ||
if (typeof result !== "string" || result.length === 0) { | ||
const stringifiedArgs = require("util").inspect(args); | ||
throw new Error(`Inflector for '${key}' returned '${String(result)}'; expected non-empty string\n` + `See: https://github.com/graphile/graphile-build/blob/master/packages/graphile-build-pg/src/inflections.js\n` + `Arguments passed to ${key}:\n${stringifiedArgs}`); | ||
} | ||
return result; | ||
}; | ||
return memo; | ||
}, {}); | ||
} | ||
const newInflector = exports.newInflector = (overrides = undefined, { | ||
@@ -41,3 +60,3 @@ constantCase, | ||
return (0, _assign2.default)({ | ||
return preventEmptyResult((0, _assign2.default)({ | ||
pluralize, | ||
@@ -56,8 +75,78 @@ argument(name, index) { | ||
}, | ||
enumName(value) { | ||
enumName(inValue) { | ||
let value = inValue; | ||
if (value === "") { | ||
return "_EMPTY_"; | ||
} | ||
const valueWithAsterisksReplaced = value.replace(/\*/g, "_ASTERISK_").replace(/^(_?)_+ASTERISK/, "$1ASTERISK").replace(/ASTERISK_(_?)_*$/, "ASTERISK$1"); | ||
return valueWithAsterisksReplaced; | ||
// Some enums use asterisks to signify wildcards - this might be for | ||
// the whole item, or prefixes/suffixes, or even in the middle. This | ||
// is provided on a best efforts basis, if it doesn't suit your | ||
// purposes then please pass a custom inflector as mentioned below. | ||
value = value.replace(/\*/g, "_ASTERISK_").replace(/^(_?)_+ASTERISK/, "$1ASTERISK").replace(/ASTERISK_(_?)_*$/, "ASTERISK$1"); | ||
// This is a best efforts replacement for common symbols that you | ||
// might find in enums. Generally we only support enums that are | ||
// alphanumeric, if these replacements don't work for you, you should | ||
// pass a custom inflector that replaces this `enumName` method | ||
// with one of your own chosing. | ||
value = { | ||
// SQL comparison operators | ||
">": "GREATER_THAN", | ||
">=": "GREATER_THAN_OR_EQUAL", | ||
"=": "EQUAL", | ||
"!=": "NOT_EQUAL", | ||
"<>": "DIFFERENT", | ||
"<=": "LESS_THAN_OR_EQUAL", | ||
"<": "LESS_THAN", | ||
// PostgreSQL LIKE shortcuts | ||
"~~": "LIKE", | ||
"~~*": "ILIKE", | ||
"!~~": "NOT_LIKE", | ||
"!~~*": "NOT_ILIKE", | ||
// '~' doesn't necessarily represent regexps, but the three | ||
// operators following it likely do, so we'll use the word TILDE | ||
// in all for consistency. | ||
"~": "TILDE", | ||
"~*": "TILDE_ASTERISK", | ||
"!~": "NOT_TILDE", | ||
"!~*": "NOT_TILDE_ASTERISK", | ||
// A number of other symbols where we're not sure of their | ||
// meaning. We give them common generic names so that they're | ||
// suitable for multiple purposes, e.g. favouring 'PLUS' over | ||
// 'ADDITION' and 'DOT' over 'FULL_STOP' | ||
"%": "PERCENT", | ||
"+": "PLUS", | ||
"-": "MINUS", | ||
"/": "SLASH", | ||
"\\": "BACKSLASH", | ||
_: "UNDERSCORE", | ||
"#": "POUND", | ||
"£": "STERLING", | ||
$: "DOLLAR", | ||
"&": "AMPERSAND", | ||
"@": "AT", | ||
"'": "APOSTROPHE", | ||
'"': "QUOTE", | ||
"`": "BACKTICK", | ||
":": "COLON", | ||
";": "SEMICOLON", | ||
"!": "EXCLAMATION_POINT", | ||
"?": "QUESTION_MARK", | ||
",": "COMMA", | ||
".": "DOT", | ||
"^": "CARET", | ||
"|": "BAR", | ||
"[": "OPEN_BRACKET", | ||
"]": "CLOSE_BRACKET", | ||
"(": "OPEN_PARENTHESIS", | ||
")": "CLOSE_PARENTHESIS", | ||
"{": "OPEN_BRACE", | ||
"}": "CLOSE_BRACE" | ||
}[value] || value; | ||
return value; | ||
}, | ||
@@ -172,3 +261,3 @@ enumType(name) { | ||
} | ||
}, overrides); | ||
}, overrides)); | ||
}; | ||
@@ -175,0 +264,0 @@ |
@@ -27,3 +27,12 @@ "use strict"; | ||
exports.default = function PgBackwardRelationPlugin(builder, { pgInflection: inflection }) { | ||
const OMIT = 0; | ||
const DEPRECATED = 1; | ||
const ONLY = 2; | ||
exports.default = function PgBackwardRelationPlugin(builder, { pgInflection: inflection, pgLegacyRelations }) { | ||
const legacyRelationMode = { | ||
only: ONLY, | ||
deprecated: DEPRECATED | ||
}[pgLegacyRelations] || OMIT; | ||
builder.hook("GraphQLObjectType:fields", (fields, { | ||
@@ -58,2 +67,3 @@ extend, | ||
const foreignTable = introspectionResultsByKind.classById[constraint.foreignClassId]; | ||
const foreignTableTypeName = inflection.tableType(foreignTable.name, foreignTable.namespace.name); | ||
const gqlForeignTableType = pgGetGqlTypeByTypeId(foreignTable.type.id); | ||
@@ -76,3 +86,7 @@ if (!gqlForeignTableType) { | ||
} | ||
const singleKey = keys.length === 1 ? keys[0] : null; | ||
const isUnique = !!(singleKey && introspectionResultsByKind.constraint.find(c => c.classId === singleKey.classId && c.keyAttributeNums.length === 1 && c.keyAttributeNums[0] === singleKey.num && (c.type === "p" || c.type === "u"))); | ||
const isDeprecated = isUnique && legacyRelationMode === DEPRECATED; | ||
const simpleKeys = keys.map(k => ({ | ||
@@ -83,54 +97,100 @@ column: k.name, | ||
})); | ||
const fieldName = inflection.manyRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name); | ||
const manyRelationFieldName = inflection.manyRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name); | ||
const singleRelationFieldName = isUnique ? inflection.singleRelationByKeys(simpleKeys, table.name, table.namespace.name, foreignTable.name, foreignTable.namespace.name) : null; | ||
const primaryKeyConstraint = introspectionResultsByKind.constraint.filter(con => con.classId === table.id).filter(con => con.type === "p")[0]; | ||
const primaryKeys = primaryKeyConstraint && primaryKeyConstraint.keyAttributeNums.map(num => attributes.filter(attr => attr.num === num)[0]); | ||
memo[fieldName] = fieldWithHooks(fieldName, ({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => { | ||
addDataGenerator(parsedResolveInfoFragment => { | ||
return { | ||
pgQuery: queryBuilder => { | ||
queryBuilder.select(() => { | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ConnectionType); | ||
const tableAlias = sql.identifier((0, _symbol2.default)()); | ||
const foreignTableAlias = queryBuilder.getTableAlias(); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
withPagination: true, | ||
withPaginationAsFields: false | ||
}, innerQueryBuilder => { | ||
if (primaryKeys) { | ||
innerQueryBuilder.beforeLock("orderBy", () => { | ||
// append order by primary key to the list of orders | ||
if (!innerQueryBuilder.isOrderUnique(false)) { | ||
innerQueryBuilder.data.cursorPrefix = ["primary_key_asc"]; | ||
primaryKeys.forEach(key => { | ||
innerQueryBuilder.orderBy(sql.fragment`${innerQueryBuilder.getTableAlias()}.${sql.identifier(key.name)}`, true); | ||
}); | ||
innerQueryBuilder.setOrderIsUnique(); | ||
} | ||
const shouldAddSingleRelation = isUnique && legacyRelationMode !== ONLY; | ||
const shouldAddManyRelation = !isUnique || legacyRelationMode === DEPRECATED || legacyRelationMode === ONLY; | ||
if (shouldAddSingleRelation) { | ||
memo[singleRelationFieldName] = fieldWithHooks(singleRelationFieldName, ({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => { | ||
addDataGenerator(parsedResolveInfoFragment => { | ||
return { | ||
pgQuery: queryBuilder => { | ||
queryBuilder.select(() => { | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, gqlTableType); | ||
const tableAlias = sql.identifier((0, _symbol2.default)()); | ||
const foreignTableAlias = queryBuilder.getTableAlias(); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
asJson: true, | ||
addNullCase: true, | ||
withPagination: false | ||
}, innerQueryBuilder => { | ||
keys.forEach((key, i) => { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
} | ||
keys.forEach((key, i) => { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
}); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
} | ||
}; | ||
}); | ||
return { | ||
description: `Reads a single \`${tableTypeName}\` that is related to this \`${foreignTableTypeName}\`.`, | ||
type: gqlTableType, | ||
args: {}, | ||
resolve: (data, _args, _context, resolveInfo) => { | ||
const alias = getAliasFromResolveInfo(resolveInfo); | ||
return data[alias]; | ||
} | ||
}; | ||
}, { | ||
pgFieldIntrospection: table | ||
}); | ||
const ConnectionType = getTypeByName(inflection.connection(gqlTableType.name)); | ||
return { | ||
description: `Reads and enables pagination through a set of \`${tableTypeName}\`.`, | ||
type: new GraphQLNonNull(ConnectionType), | ||
args: {}, | ||
resolve: (data, _args, _context, resolveInfo) => { | ||
const alias = getAliasFromResolveInfo(resolveInfo); | ||
return (0, _addStartEndCursor2.default)(data[alias]); | ||
} | ||
}; | ||
}, { | ||
isPgFieldConnection: true, | ||
pgFieldIntrospection: table | ||
}); | ||
} | ||
if (shouldAddManyRelation) { | ||
memo[manyRelationFieldName] = fieldWithHooks(manyRelationFieldName, ({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => { | ||
addDataGenerator(parsedResolveInfoFragment => { | ||
return { | ||
pgQuery: queryBuilder => { | ||
queryBuilder.select(() => { | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ConnectionType); | ||
const tableAlias = sql.identifier((0, _symbol2.default)()); | ||
const foreignTableAlias = queryBuilder.getTableAlias(); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
withPagination: true, | ||
withPaginationAsFields: false | ||
}, innerQueryBuilder => { | ||
if (primaryKeys) { | ||
innerQueryBuilder.beforeLock("orderBy", () => { | ||
// append order by primary key to the list of orders | ||
if (!innerQueryBuilder.isOrderUnique(false)) { | ||
innerQueryBuilder.data.cursorPrefix = ["primary_key_asc"]; | ||
primaryKeys.forEach(key => { | ||
innerQueryBuilder.orderBy(sql.fragment`${innerQueryBuilder.getTableAlias()}.${sql.identifier(key.name)}`, true); | ||
}); | ||
innerQueryBuilder.setOrderIsUnique(); | ||
} | ||
}); | ||
} | ||
keys.forEach((key, i) => { | ||
innerQueryBuilder.where(sql.fragment`${tableAlias}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); | ||
}); | ||
}); | ||
return sql.fragment`(${query})`; | ||
}, parsedResolveInfoFragment.alias); | ||
} | ||
}; | ||
}); | ||
const ConnectionType = getTypeByName(inflection.connection(gqlTableType.name)); | ||
return { | ||
description: `Reads and enables pagination through a set of \`${tableTypeName}\`.`, | ||
type: new GraphQLNonNull(ConnectionType), | ||
args: {}, | ||
resolve: (data, _args, _context, resolveInfo) => { | ||
const alias = getAliasFromResolveInfo(resolveInfo); | ||
return (0, _addStartEndCursor2.default)(data[alias]); | ||
}, | ||
deprecationReason: isDeprecated ? // $FlowFixMe | ||
`Please use ${singleRelationFieldName} instead` : undefined | ||
}; | ||
}, { | ||
isPgFieldConnection: true, | ||
pgFieldIntrospection: table | ||
}); | ||
} | ||
return memo; | ||
@@ -137,0 +197,0 @@ }, {}), `Adding backward relations for ${Self.name}`); |
@@ -435,3 +435,3 @@ "use strict"; | ||
} catch (e) { | ||
const error = new Error(`Error occurred when processing type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`); | ||
const error = new Error(`Error occurred when processing database type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`); | ||
// $FlowFixMe | ||
@@ -438,0 +438,0 @@ error.originalError = e; |
{ | ||
"name": "graphile-build-pg", | ||
"version": "0.1.0-alpha.41", | ||
"version": "4.0.0-alpha", | ||
"description": "Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build", | ||
@@ -40,3 +40,3 @@ "main": "index.js", | ||
"debug": ">=2 <3", | ||
"graphile-build": "0.1.0-alpha.39", | ||
"graphile-build": "4.0.0-alpha", | ||
"graphql-iso-date": "^3.2.0", | ||
@@ -47,3 +47,2 @@ "graphql-type-json": "^0.1.4", | ||
"lru-cache": "4.1.1", | ||
"pg": ">=6.1.0 <8", | ||
"pg-range-parser": "^1.0.0", | ||
@@ -55,3 +54,3 @@ "pg-sql2": "^1.0.0-beta.3", | ||
"peerDependencies": { | ||
"pg": ">=6 <7" | ||
"pg": ">=6.1.0 <8" | ||
}, | ||
@@ -58,0 +57,0 @@ "devDependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1616836
14
11024
+ Addedgraphile-build@4.0.0-alpha(transitive)
+ Addedgraphql-parse-resolve-info@4.0.0-alpha(transitive)
- Removedpg@>=6.1.0 <8
- Removedgraphile-build@0.1.0-alpha.39(transitive)
- Removedgraphql-parse-resolve-info@0.1.0-alpha.18(transitive)
Updatedgraphile-build@4.0.0-alpha