graphile-build-pg
Advanced tools
Comparing version 4.0.0-rc.1 to 4.0.0-rc.2
@@ -6,8 +6,3 @@ "use strict"; | ||
}); | ||
exports.GraphQLJson = exports.GraphQLJSON = undefined; | ||
var _graphql = require("graphql"); | ||
var _language = require("graphql/language"); | ||
exports.default = makeGraphQLJSONTypes; | ||
// This file is based on | ||
@@ -42,52 +37,58 @@ // https://github.com/taion/graphql-type-json/blob/6e45ae4ee0a60f8f3565c8c980a82c7d9b98d3f5/src/index.js | ||
*/ | ||
function identity(value) { | ||
return value; | ||
} | ||
function makeGraphQLJSONTypes(graphql) { | ||
const { GraphQLScalarType, Kind } = graphql; | ||
function parseLiteral(ast, variables) { | ||
switch (ast.kind) { | ||
case _language.Kind.STRING: | ||
case _language.Kind.BOOLEAN: | ||
return ast.value; | ||
case _language.Kind.INT: | ||
case _language.Kind.FLOAT: | ||
return parseFloat(ast.value); | ||
case _language.Kind.OBJECT: | ||
{ | ||
const value = Object.create(null); | ||
ast.fields.forEach(field => { | ||
value[field.name.value] = parseLiteral(field.value, variables); | ||
}); | ||
function identity(value) { | ||
return value; | ||
} | ||
return value; | ||
} | ||
case _language.Kind.LIST: | ||
return ast.values.map(n => parseLiteral(n, variables)); | ||
case _language.Kind.NULL: | ||
return null; | ||
case _language.Kind.VARIABLE: | ||
{ | ||
const name = ast.name.value; | ||
return variables ? variables[name] : undefined; | ||
} | ||
default: | ||
return undefined; | ||
function parseLiteral(ast, variables) { | ||
switch (ast.kind) { | ||
case Kind.STRING: | ||
case Kind.BOOLEAN: | ||
return ast.value; | ||
case Kind.INT: | ||
case Kind.FLOAT: | ||
return parseFloat(ast.value); | ||
case Kind.OBJECT: | ||
{ | ||
const value = Object.create(null); | ||
ast.fields.forEach(field => { | ||
value[field.name.value] = parseLiteral(field.value, variables); | ||
}); | ||
return value; | ||
} | ||
case Kind.LIST: | ||
return ast.values.map(n => parseLiteral(n, variables)); | ||
case Kind.NULL: | ||
return null; | ||
case Kind.VARIABLE: | ||
{ | ||
const name = ast.name.value; | ||
return variables ? variables[name] : undefined; | ||
} | ||
default: | ||
return undefined; | ||
} | ||
} | ||
} | ||
const GraphQLJSON = exports.GraphQLJSON = new _graphql.GraphQLScalarType({ | ||
name: "JSON", | ||
description: "The `JSON` scalar type represents JSON values as specified by " + "[ECMA-404](http://www.ecma-international.org/" + "publications/files/ECMA-ST/ECMA-404.pdf).", | ||
serialize: identity, | ||
parseValue: identity, | ||
parseLiteral | ||
}); | ||
const GraphQLJSON = new GraphQLScalarType({ | ||
name: "JSON", | ||
description: "The `JSON` scalar type represents JSON values as specified by " + "[ECMA-404](http://www.ecma-international.org/" + "publications/files/ECMA-ST/ECMA-404.pdf).", | ||
serialize: identity, | ||
parseValue: identity, | ||
parseLiteral | ||
}); | ||
const GraphQLJson = exports.GraphQLJson = new _graphql.GraphQLScalarType({ | ||
name: "Json", | ||
description: "The `Json` scalar type represents JSON values as specified by " + "[ECMA-404](http://www.ecma-international.org/" + "publications/files/ECMA-ST/ECMA-404.pdf).", | ||
serialize: identity, | ||
parseValue: identity, | ||
parseLiteral | ||
}); | ||
const GraphQLJson = new GraphQLScalarType({ | ||
name: "Json", | ||
description: "The `Json` scalar type represents JSON values as specified by " + "[ECMA-404](http://www.ecma-international.org/" + "publications/files/ECMA-ST/ECMA-404.pdf).", | ||
serialize: identity, | ||
parseValue: identity, | ||
parseLiteral | ||
}); | ||
return { GraphQLJSON, GraphQLJson }; | ||
} | ||
//# sourceMappingURL=GraphQLJSON.js.map |
@@ -12,12 +12,13 @@ "use strict"; | ||
*/ | ||
const CREATE = "create"; | ||
const CREATE = exports.CREATE = "create"; | ||
const READ = "read"; | ||
const UPDATE = "update"; | ||
const DELETE = "delete"; | ||
const ALL = "all"; | ||
const MANY = "many"; | ||
const ORDER = "order"; | ||
const FILTER = "filter"; | ||
const EXECUTE = "execute"; | ||
const READ = exports.READ = "read"; | ||
const UPDATE = exports.UPDATE = "update"; | ||
const DELETE = exports.DELETE = "delete"; | ||
const FILTER = exports.FILTER = "filter"; | ||
const ORDER = exports.ORDER = "order"; | ||
const ALL = exports.ALL = "all"; | ||
const MANY = exports.MANY = "many"; | ||
const EXECUTE = exports.EXECUTE = "execute"; | ||
const BASE = exports.BASE = "base"; | ||
@@ -33,3 +34,4 @@ const aliases = { | ||
M: MANY, | ||
X: EXECUTE | ||
X: EXECUTE, | ||
B: BASE | ||
}; | ||
@@ -36,0 +38,0 @@ |
@@ -12,17 +12,6 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _addStartEndCursor = require("./addStartEndCursor"); | ||
var _addStartEndCursor2 = _interopRequireDefault(_addStartEndCursor); | ||
var _viaTemporaryTable = require("./viaTemporaryTable"); | ||
var _viaTemporaryTable2 = _interopRequireDefault(_viaTemporaryTable); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const debugSql = (0, _debug2.default)("graphile-build-pg:sql"); | ||
const firstValue = obj => { | ||
@@ -40,4 +29,4 @@ let firstKey; | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
getTypeByName, | ||
@@ -52,3 +41,3 @@ pgSql: sql, | ||
pgStrictFunctions: strictFunctions, | ||
pgTweakFragmentForType, | ||
pgTweakFragmentForTypeAndModifier, | ||
graphql: { | ||
@@ -66,3 +55,6 @@ GraphQLNonNull, | ||
}, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgAddStartEndCursor: addStartEndCursor, | ||
pgViaTemporaryTable: viaTemporaryTable | ||
}, { | ||
@@ -101,5 +93,24 @@ fieldWithHooks, | ||
const requiredArgCount = Math.max(0, argNames.length - proc.argDefaultsNum); | ||
const variantFromName = (name, _type) => { | ||
if (name.match(/(_p|P)atch$/)) { | ||
return "patch"; | ||
} | ||
return null; | ||
}; | ||
const variantFromTags = (tags, idx) => { | ||
const variant = tags[`arg${idx}variant`]; | ||
if (variant && variant.match && variant.match(/^[0-9]+$/)) { | ||
return parseInt(variant, 10); | ||
} | ||
return variant; | ||
}; | ||
const notNullArgCount = proc.isStrict || strictFunctions ? requiredArgCount : 0; | ||
const argGqlTypes = argTypes.map((type, idx) => { | ||
const Type = pgGetGqlInputTypeByTypeId(type.id) || GraphQLString; | ||
// TODO: PG10 doesn't support the equivalent of pg_attribute.atttypemod on function return values, but maybe a later version might | ||
const variant = variantFromTags(proc.tags, idx) || variantFromName(argNames[idx], type); | ||
const Type = pgGetGqlInputTypeByTypeIdAndModifier(type.id, variant); | ||
if (!Type) { | ||
const hint = type.class ? `; you might want to use smart comments, e.g. 'COMMENT ON FUNCTION "${proc.namespace.name}"."${proc.name}"(${argTypes.map(t => `"${t.namespaceName}"."${t.name}"`).join(", ")}) IS E'@arg${idx}variant base';"` : ""; | ||
throw new Error(`Could not determine type for argument ${idx} ('${argNames[idx]}') of function '${proc.name}'${hint}`); | ||
} | ||
if (idx >= notNullArgCount) { | ||
@@ -124,3 +135,3 @@ return Type; | ||
let returnFirstValueAsValue = false; | ||
const TableType = returnTypeTable && pgGetGqlTypeByTypeId(returnTypeTable.type.id); | ||
const TableType = returnTypeTable && pgGetGqlTypeByTypeIdAndModifier(returnTypeTable.type.id, null); | ||
@@ -154,3 +165,4 @@ const isTableLike = TableType && isCompositeType(TableType) || false; | ||
} else { | ||
const Type = pgGetGqlTypeByTypeId(returnType.id) || GraphQLString; | ||
// TODO: PG10 doesn't support the equivalent of pg_attribute.atttypemod on function return values, but maybe a later version might | ||
const Type = pgGetGqlTypeByTypeIdAndModifier(returnType.id, null) || GraphQLString; | ||
if (proc.returnsSet) { | ||
@@ -226,3 +238,3 @@ const connectionTypeName = inflection.scalarFunctionConnection(proc); | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ReturnType); | ||
const query = (0, _queryFromResolveData2.default)(sqlMutationQuery, functionAlias, resolveData, { | ||
const query = queryFromResolveData(sqlMutationQuery, functionAlias, resolveData, { | ||
withPagination: !forceList && !isMutation && proc.returnsSet, | ||
@@ -236,5 +248,6 @@ withPaginationAsFields: !forceList && !isMutation && proc.returnsSet && !computed, | ||
if (returnTypeTable) { | ||
innerQueryBuilder.select(pgTweakFragmentForType(sql.fragment`${functionAlias}`, returnTypeTable.type), "value"); | ||
innerQueryBuilder.select(pgTweakFragmentForTypeAndModifier(sql.fragment`${functionAlias}`, returnTypeTable.type, null, resolveData), "value"); | ||
} else { | ||
innerQueryBuilder.select(pgTweakFragmentForType(sql.fragment`${functionAlias}.${functionAlias}`, returnType), "value"); | ||
innerQueryBuilder.select(pgTweakFragmentForTypeAndModifier(sql.fragment`${functionAlias}.${functionAlias}`, returnType, null, // We can't determine a type modifier for functions | ||
resolveData), "value"); | ||
} | ||
@@ -346,3 +359,3 @@ } | ||
if (proc.returnsSet && !isMutation && !forceList) { | ||
return (0, _addStartEndCursor2.default)({ | ||
return addStartEndCursor({ | ||
...value, | ||
@@ -370,3 +383,3 @@ data: value.data ? value.data.map(scalarAwarePg2gql) : null | ||
await pgClient.query("SAVEPOINT graphql_mutation"); | ||
queryResultRows = await (0, _viaTemporaryTable2.default)(pgClient, isVoid ? null : sql.identifier(returnType.namespaceName, returnType.name), sql.query`select ${isPgClass ? sql.query`${intermediateIdentifier}.*` : sql.query`${intermediateIdentifier}.${intermediateIdentifier} as ${functionAlias}`} from ${sqlMutationQuery} ${intermediateIdentifier}`, functionAlias, query, isPgClass); | ||
queryResultRows = await viaTemporaryTable(pgClient, isVoid ? null : sql.identifier(returnType.namespaceName, returnType.name), sql.query`select ${isPgClass ? sql.query`${intermediateIdentifier}.*` : sql.query`${intermediateIdentifier}.${intermediateIdentifier} as ${functionAlias}`} from ${sqlMutationQuery} ${intermediateIdentifier}`, functionAlias, query, isPgClass); | ||
await pgClient.query("RELEASE SAVEPOINT graphql_mutation"); | ||
@@ -401,3 +414,3 @@ } catch (e) { | ||
// Connection | ||
return (0, _addStartEndCursor2.default)({ | ||
return addStartEndCursor({ | ||
...row, | ||
@@ -404,0 +417,0 @@ data: row.data ? row.data.map(scalarAwarePg2gql) : null |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _debug = require("debug"); | ||
@@ -16,10 +12,2 @@ | ||
var _addStartEndCursor = require("./addStartEndCursor"); | ||
var _addStartEndCursor2 = _interopRequireDefault(_addStartEndCursor); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -37,7 +25,10 @@ | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgSql: sql, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
inflection, | ||
graphql: { GraphQLList, GraphQLNonNull } | ||
graphql: { GraphQLList, GraphQLNonNull }, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgAddStartEndCursor: addStartEndCursor, | ||
pgOmit: omit | ||
} = build; | ||
@@ -48,7 +39,7 @@ const { fieldWithHooks, scope: { isRootQuery } } = context; | ||
} | ||
return extend(fields, introspectionResultsByKind.class.filter(table => table.isSelectable).filter(table => table.namespace).reduce((memo, table) => { | ||
if ((0, _omit2.default)(table, "all")) { | ||
return extend(fields, introspectionResultsByKind.class.filter(table => table.isSelectable).filter(table => table.namespace).filter(table => !omit(table, "all")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
if (!TableType) { | ||
return memo; | ||
} | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const tableTypeName = TableType.name; | ||
@@ -79,3 +70,3 @@ const ConnectionType = getTypeByName(inflection.connection(TableType.name)); | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, resolveInfo.returnType); | ||
const query = (0, _queryFromResolveData2.default)(sqlFullTableName, undefined, resolveData, { | ||
const query = queryFromResolveData(sqlFullTableName, undefined, resolveData, { | ||
withPaginationAsFields: isConnection | ||
@@ -109,3 +100,3 @@ }, builder => { | ||
const { rows: [row] } = result; | ||
return (0, _addStartEndCursor2.default)(row); | ||
return addStartEndCursor(row); | ||
} else { | ||
@@ -112,0 +103,0 @@ return result.rows; |
@@ -11,14 +11,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _addStartEndCursor = require("./addStartEndCursor"); | ||
var _addStartEndCursor2 = _interopRequireDefault(_addStartEndCursor); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -28,2 +16,3 @@ | ||
const OMIT = 0; | ||
@@ -44,3 +33,3 @@ const DEPRECATED = 1; | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
@@ -51,3 +40,6 @@ pgSql: sql, | ||
graphql: { GraphQLNonNull, GraphQLList }, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgAddStartEndCursor: addStartEndCursor, | ||
pgOmit: omit | ||
} = build; | ||
@@ -67,3 +59,3 @@ const { | ||
return extend(fields, foreignKeyConstraints.reduce((memo, constraint) => { | ||
if ((0, _omit2.default)(constraint, "read")) { | ||
if (omit(constraint, "read")) { | ||
return memo; | ||
@@ -73,3 +65,3 @@ } | ||
const tableTypeName = inflection.tableType(table); | ||
const gqlTableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const gqlTableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
if (!gqlTableType) { | ||
@@ -81,3 +73,3 @@ debug(`Could not determine type for table with id ${constraint.classId}`); | ||
const foreignTableTypeName = inflection.tableType(foreignTable); | ||
const gqlForeignTableType = pgGetGqlTypeByTypeId(foreignTable.type.id); | ||
const gqlForeignTableType = pgGetGqlTypeByTypeIdAndModifier(foreignTable.type.id, null); | ||
if (!gqlForeignTableType) { | ||
@@ -99,6 +91,6 @@ debug(`Could not determine type for foreign table with id ${constraint.foreignClassId}`); | ||
} | ||
if (keys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (keys.some(key => omit(key, "read"))) { | ||
return memo; | ||
} | ||
if (foreignKeys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (foreignKeys.some(key => omit(key, "read"))) { | ||
return memo; | ||
@@ -120,3 +112,3 @@ } | ||
if (shouldAddSingleRelation && !(0, _omit2.default)(table, "read")) { | ||
if (shouldAddSingleRelation && !omit(table, "read")) { | ||
memo[singleRelationFieldName] = fieldWithHooks(singleRelationFieldName, ({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => { | ||
@@ -130,3 +122,3 @@ addDataGenerator(parsedResolveInfoFragment => { | ||
const foreignTableAlias = queryBuilder.getTableAlias(); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
const query = queryFromResolveData(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
asJson: true, | ||
@@ -163,3 +155,3 @@ addNullCase: true, | ||
} | ||
if (shouldAddManyRelation && !(0, _omit2.default)(table, "many")) { | ||
if (shouldAddManyRelation && !omit(table, "many")) { | ||
const manyRelationFieldName = isConnection ? inflection.manyRelationByKeys(keys, table, foreignTable, constraint) : inflection.manyRelationByKeysSimple(keys, table, foreignTable, constraint); | ||
@@ -175,3 +167,3 @@ | ||
const foreignTableAlias = queryBuilder.getTableAlias(); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
const query = queryFromResolveData(sql.identifier(schema.name, table.name), tableAlias, resolveData, { | ||
withPagination: isConnection, | ||
@@ -204,3 +196,3 @@ withPaginationAsFields: false, | ||
const ConnectionType = getTypeByName(inflection.connection(gqlTableType.name)); | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
return { | ||
@@ -213,3 +205,3 @@ description: `Reads and enables pagination through a set of \`${tableTypeName}\`.`, | ||
if (isConnection) { | ||
return (0, _addStartEndCursor2.default)(data[safeAlias]); | ||
return addStartEndCursor(data[safeAlias]); | ||
} else { | ||
@@ -216,0 +208,0 @@ return data[safeAlias]; |
@@ -14,2 +14,26 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _addStartEndCursor = require("./addStartEndCursor"); | ||
var _addStartEndCursor2 = _interopRequireDefault(_addStartEndCursor); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
var _makeProcField = require("./makeProcField"); | ||
var _makeProcField2 = _interopRequireDefault(_makeProcField); | ||
var _parseIdentifier = require("../parseIdentifier"); | ||
var _parseIdentifier2 = _interopRequireDefault(_parseIdentifier); | ||
var _viaTemporaryTable = require("./viaTemporaryTable"); | ||
var _viaTemporaryTable2 = _interopRequireDefault(_viaTemporaryTable); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -33,3 +57,41 @@ | ||
exports.default = function PgBasicsPlugin(builder, { pgStrictFunctions = false, pgColumnFilter = defaultPgColumnFilter }) { | ||
function omitWithRBACChecks(entity, permission) { | ||
const ORDINARY_TABLE = "r"; | ||
const VIEW = "v"; | ||
const MATERIALIZED_VIEW = "m"; | ||
const isTableLike = entity => entity && entity.kind === "class" && (entity.classKind === ORDINARY_TABLE || entity.classKind === VIEW || entity.classKind === MATERIALIZED_VIEW); | ||
if (entity.kind === "procedure") { | ||
if (permission === _omit.EXECUTE && !entity.aclExecutable) { | ||
return true; | ||
} | ||
} else if (entity.kind === "class" && isTableLike(entity)) { | ||
const tableEntity = entity; | ||
if ((permission === _omit.READ || permission === _omit.ALL || permission === _omit.MANY) && !tableEntity.aclSelectable) { | ||
return true; | ||
} else if (permission === _omit.CREATE && !tableEntity.aclInsertable && !tableEntity.attributes.some(attr => attr.aclInsertable)) { | ||
return true; | ||
} else if (permission === _omit.UPDATE && !tableEntity.aclUpdatable && !tableEntity.attributes.some(attr => attr.aclUpdatable)) { | ||
return true; | ||
} else if (permission === _omit.DELETE && !tableEntity.aclDeletable) { | ||
return true; | ||
} | ||
} else if (entity.kind === "attribute" && isTableLike(entity.class)) { | ||
const attributeEntity = entity; | ||
if ((permission === _omit.READ || permission === _omit.FILTER || permission === _omit.ORDER) && !attributeEntity.aclSelectable) { | ||
return true; | ||
} else if (permission === _omit.CREATE && !attributeEntity.aclInsertable) { | ||
return true; | ||
} else if (permission === _omit.UPDATE && !attributeEntity.aclUpdatable) { | ||
return true; | ||
} | ||
} | ||
return (0, _omit2.default)(entity, permission); | ||
} | ||
exports.default = function PgBasicsPlugin(builder, { | ||
pgStrictFunctions = false, | ||
pgColumnFilter = defaultPgColumnFilter, | ||
pgIgnoreRBAC = false | ||
}) { | ||
const pgOmit = pgIgnoreRBAC ? _omit2.default : omitWithRBACChecks; | ||
builder.hook("build", build => { | ||
@@ -40,3 +102,9 @@ return build.extend(build, { | ||
pgStrictFunctions, | ||
pgColumnFilter | ||
pgColumnFilter, | ||
pgQueryFromResolveData: _queryFromResolveData2.default, | ||
pgAddStartEndCursor: _addStartEndCursor2.default, | ||
pgOmit, | ||
pgMakeProcField: _makeProcField2.default, | ||
pgParseIdentifier: _parseIdentifier2.default, | ||
pgViaTemporaryTable: _viaTemporaryTable2.default | ||
}); | ||
@@ -63,2 +131,5 @@ }); | ||
}, | ||
baseInputType(typeName) { | ||
return this.upperCamelCase(`${typeName}-base-input`); | ||
}, | ||
patchField(itemName) { | ||
@@ -65,0 +136,0 @@ return this.camelCase(`${itemName}-patch`); |
@@ -7,12 +7,3 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const nullableIf = (GraphQLNonNull, condition, Type) => condition ? Type : new GraphQLNonNull(Type); | ||
@@ -24,3 +15,3 @@ | ||
extend, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
@@ -30,5 +21,7 @@ pgSql: sql, | ||
graphql: { GraphQLString, GraphQLNonNull }, | ||
pgTweakFragmentForType, | ||
pgTweakFragmentForTypeAndModifier, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit | ||
} = build; | ||
@@ -43,6 +36,3 @@ const { | ||
} | ||
return extend(fields, introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).reduce((memo, attr) => { | ||
if ((0, _omit2.default)(attr, "read")) { | ||
return memo; | ||
} | ||
return extend(fields, introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !omit(attr, "read")).reduce((memo, attr) => { | ||
/* | ||
@@ -64,7 +54,7 @@ attr = | ||
memo[fieldName] = fieldWithHooks(fieldName, ({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => { | ||
const ReturnType = pgGetGqlTypeByTypeId(attr.typeId) || GraphQLString; | ||
const ReturnType = pgGetGqlTypeByTypeIdAndModifier(attr.typeId, attr.typeModifier) || GraphQLString; | ||
addDataGenerator(parsedResolveInfoFragment => { | ||
return { | ||
pgQuery: queryBuilder => { | ||
const getSelectValueForFieldAndType = (sqlFullName, type) => { | ||
const getSelectValueForFieldAndTypeAndModifier = (sqlFullName, type, typeModifier) => { | ||
if (type.isPgArray) { | ||
@@ -79,3 +69,3 @@ const ident = sql.identifier(Symbol()); | ||
( | ||
select json_agg(${getSelectValueForFieldAndType(ident, type.arrayItemType)}) | ||
select json_agg(${getSelectValueForFieldAndTypeAndModifier(ident, type.arrayItemType, typeModifier)}) | ||
from unnest(${sqlFullName}) as ${ident} | ||
@@ -86,13 +76,15 @@ ) | ||
`; | ||
} else if (type.type === "c") { | ||
} else { | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, ReturnType); | ||
const jsonBuildObject = (0, _queryFromResolveData2.default)(sql.identifier(Symbol()), // Ignore! | ||
sqlFullName, resolveData, { onlyJsonField: true, addNullCase: true }); | ||
return jsonBuildObject; | ||
} else { | ||
return pgTweakFragmentForType(sqlFullName, type); | ||
if (type.type === "c") { | ||
const jsonBuildObject = queryFromResolveData(sql.identifier(Symbol()), // Ignore! | ||
sqlFullName, resolveData, { onlyJsonField: true, addNullCase: true }); | ||
return jsonBuildObject; | ||
} else { | ||
return pgTweakFragmentForTypeAndModifier(sqlFullName, type, typeModifier, resolveData); | ||
} | ||
} | ||
}; | ||
queryBuilder.select(getSelectValueForFieldAndType(sql.fragment`(${queryBuilder.getTableAlias()}.${sql.identifier(attr.name)})`, // The brackets are necessary to stop the parser getting confused, ref: https://www.postgresql.org/docs/9.6/static/rowtypes.html#ROWTYPES-ACCESSING | ||
attr.type), fieldName); | ||
queryBuilder.select(getSelectValueForFieldAndTypeAndModifier(sql.fragment`(${queryBuilder.getTableAlias()}.${sql.identifier(attr.name)})`, // The brackets are necessary to stop the parser getting confused, ref: https://www.postgresql.org/docs/9.6/static/rowtypes.html#ROWTYPES-ACCESSING | ||
attr.type, attr.typeModifier), fieldName); | ||
} | ||
@@ -115,7 +107,8 @@ }; | ||
extend, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
graphql: { GraphQLString, GraphQLNonNull }, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
@@ -127,2 +120,3 @@ const { | ||
isPgPatch, | ||
isPgBaseInput, | ||
pgIntrospection: table, | ||
@@ -137,6 +131,3 @@ pgAddSubfield | ||
} | ||
return extend(fields, introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).reduce((memo, attr) => { | ||
if ((0, _omit2.default)(attr, isPgPatch ? "update" : "create")) { | ||
return memo; | ||
} | ||
return extend(fields, introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !omit(attr, isPgBaseInput ? "base" : isPgPatch ? "update" : "create")).reduce((memo, attr) => { | ||
const fieldName = inflection.column(attr); | ||
@@ -148,3 +139,3 @@ if (memo[fieldName]) { | ||
description: attr.description, | ||
type: nullableIf(GraphQLNonNull, isPgPatch || !attr.isNotNull && !attr.type.domainIsNotNull || attr.hasDefault, pgGetGqlInputTypeByTypeId(attr.typeId) || GraphQLString) | ||
type: nullableIf(GraphQLNonNull, isPgBaseInput || isPgPatch || !attr.isNotNull && !attr.type.domainIsNotNull || attr.hasDefault, pgGetGqlInputTypeByTypeIdAndModifier(attr.typeId, attr.typeModifier) || GraphQLString) | ||
}), { pgFieldIntrospection: attr }); | ||
@@ -151,0 +142,0 @@ return memo; |
@@ -7,12 +7,2 @@ "use strict"; | ||
var _makeProcField = require("./makeProcField"); | ||
var _makeProcField2 = _interopRequireDefault(_makeProcField); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function PgComputedColumnsPlugin(builder, { pgSimpleCollections }) { | ||
@@ -38,3 +28,6 @@ const hasConnections = pgSimpleCollections !== "only"; | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
inflection | ||
inflection, | ||
pgOmit: omit, | ||
pgMakeProcField: makeProcField, | ||
swallowError | ||
} = build; | ||
@@ -45,3 +38,3 @@ const tableType = introspectionResultsByKind.type.filter(type => type.type === "c" && type.namespaceId === table.namespaceId && type.classId === table.id)[0]; | ||
} | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => proc.isStable).filter(proc => proc.namespaceId === table.namespaceId).filter(proc => proc.name.startsWith(`${table.name}_`)).filter(proc => proc.argTypeIds.length > 0).filter(proc => proc.argTypeIds[0] === tableType.id).filter(proc => !(0, _omit2.default)(proc, "execute")).reduce((memo, proc) => { | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => proc.isStable).filter(proc => proc.namespaceId === table.namespaceId).filter(proc => proc.name.startsWith(`${table.name}_`)).filter(proc => proc.argTypeIds.length > 0).filter(proc => proc.argTypeIds[0] === tableType.id).filter(proc => !omit(proc, "execute")).reduce((memo, proc) => { | ||
/* | ||
@@ -70,7 +63,11 @@ proc = | ||
const fieldName = forceList ? inflection.computedColumnList(pseudoColumnName, proc, table) : inflection.computedColumn(pseudoColumnName, proc, table); | ||
memo[fieldName] = (0, _makeProcField2.default)(fieldName, proc, build, { | ||
fieldWithHooks, | ||
computed: true, | ||
forceList | ||
}); | ||
try { | ||
memo[fieldName] = makeProcField(fieldName, proc, build, { | ||
fieldWithHooks, | ||
computed: true, | ||
forceList | ||
}); | ||
} catch (e) { | ||
swallowError(e); | ||
} | ||
} | ||
@@ -77,0 +74,0 @@ if (!proc.returnsSet || hasConnections) { |
@@ -7,8 +7,2 @@ "use strict"; | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function PgConnectionArgCondition(builder) { | ||
@@ -19,8 +13,9 @@ builder.hook("init", (_, build) => { | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
graphql: { GraphQLInputObjectType, GraphQLString }, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
introspectionResultsByKind.class.filter(table => table.isSelectable && !(0, _omit2.default)(table, "filter")).filter(table => !!table.namespace).forEach(table => { | ||
introspectionResultsByKind.class.filter(table => table.isSelectable && !omit(table, "filter")).filter(table => !!table.namespace).forEach(table => { | ||
const tableTypeName = inflection.tableType(table); | ||
@@ -33,7 +28,7 @@ /* const TableConditionType = */ | ||
const { fieldWithHooks } = context; | ||
return introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !(0, _omit2.default)(attr, "filter")).reduce((memo, attr) => { | ||
return introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !omit(attr, "filter")).reduce((memo, attr) => { | ||
const fieldName = inflection.column(attr); | ||
memo[fieldName] = fieldWithHooks(fieldName, { | ||
description: `Checks for equality with the object’s \`${fieldName}\` field.`, | ||
type: pgGetGqlInputTypeByTypeId(attr.typeId) || GraphQLString | ||
type: pgGetGqlInputTypeByTypeIdAndModifier(attr.typeId, attr.typeModifier) || GraphQLString | ||
}, { | ||
@@ -58,6 +53,7 @@ isPgConnectionConditionInputField: true | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
@@ -75,9 +71,9 @@ const { | ||
const shouldAddCondition = isPgFieldConnection || isPgFieldSimpleCollection; | ||
if (!shouldAddCondition || !table || table.kind !== "class" || !table.namespace || (0, _omit2.default)(table, "filter")) { | ||
if (!shouldAddCondition || !table || table.kind !== "class" || !table.namespace || omit(table, "filter")) { | ||
return args; | ||
} | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const TableConditionType = getTypeByName(inflection.conditionType(TableType.name)); | ||
const relevantAttributes = introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !(0, _omit2.default)(attr, "filter")); | ||
const relevantAttributes = introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !omit(attr, "filter")); | ||
@@ -84,0 +80,0 @@ addArgDataGenerator(function connectionCondition({ condition }) { |
@@ -11,6 +11,2 @@ "use strict"; | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -24,5 +20,6 @@ | ||
graphql: { GraphQLEnumType }, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
introspectionResultsByKind.class.filter(table => table.isSelectable && !(0, _omit2.default)(table, "order")).filter(table => !!table.namespace).forEach(table => { | ||
introspectionResultsByKind.class.filter(table => table.isSelectable && !omit(table, "order")).filter(table => !!table.namespace).forEach(table => { | ||
const tableTypeName = inflection.tableType(table); | ||
@@ -52,6 +49,7 @@ /* const TableOrderByType = */ | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgSql: sql, | ||
graphql: { GraphQLList, GraphQLNonNull }, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
@@ -69,6 +67,6 @@ const { | ||
const shouldAddOrderBy = isPgFieldConnection || isPgFieldSimpleCollection; | ||
if (!shouldAddOrderBy || !table || table.kind !== "class" || !table.namespace || !table.isSelectable || (0, _omit2.default)(table, "order")) { | ||
if (!shouldAddOrderBy || !table || table.kind !== "class" || !table.namespace || !table.isSelectable || omit(table, "order")) { | ||
return args; | ||
} | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const tableTypeName = TableType.name; | ||
@@ -75,0 +73,0 @@ const TableOrderByType = getTypeByName(inflection.orderByType(tableTypeName)); |
@@ -9,4 +9,9 @@ "use strict"; | ||
builder.hook("GraphQLObjectType:fields:field:args", (args, build, context) => { | ||
const { extend, getTypeByName, pgGetGqlTypeByTypeId, inflection } = build; | ||
const { | ||
extend, | ||
getTypeByName, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
inflection | ||
} = build; | ||
const { | ||
scope: { isPgFieldConnection, pgFieldIntrospection: table }, | ||
@@ -19,3 +24,3 @@ Self, | ||
} | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const tableTypeName = TableType.name; | ||
@@ -22,0 +27,0 @@ const TableOrderByType = getTypeByName(inflection.orderByType(tableTypeName)); |
@@ -11,10 +11,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -30,6 +22,8 @@ | ||
getSafeAliasFromAlias, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
pgSql: sql, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit | ||
} = build; | ||
@@ -56,6 +50,6 @@ const { | ||
return extend(fields, foreignKeyConstraints.reduce((memo, constraint) => { | ||
if ((0, _omit2.default)(constraint, "read")) { | ||
if (omit(constraint, "read")) { | ||
return memo; | ||
} | ||
const gqlTableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const gqlTableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const tableTypeName = gqlTableType.name; | ||
@@ -67,3 +61,3 @@ if (!gqlTableType) { | ||
const foreignTable = introspectionResultsByKind.classById[constraint.foreignClassId]; | ||
const gqlForeignTableType = pgGetGqlTypeByTypeId(foreignTable.type.id); | ||
const gqlForeignTableType = pgGetGqlTypeByTypeIdAndModifier(foreignTable.type.id, null); | ||
const foreignTableTypeName = gqlForeignTableType.name; | ||
@@ -77,3 +71,3 @@ if (!gqlForeignTableType) { | ||
} | ||
if ((0, _omit2.default)(foreignTable, "read")) { | ||
if (omit(foreignTable, "read")) { | ||
return memo; | ||
@@ -89,6 +83,6 @@ } | ||
} | ||
if (keys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (keys.some(key => omit(key, "read"))) { | ||
return memo; | ||
} | ||
if (foreignKeys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (foreignKeys.some(key => omit(key, "read"))) { | ||
return memo; | ||
@@ -106,3 +100,3 @@ } | ||
const foreignTableAlias = sql.identifier(Symbol()); | ||
const query = (0, _queryFromResolveData2.default)(sql.identifier(foreignSchema.name, foreignTable.name), foreignTableAlias, resolveData, { asJson: true }, innerQueryBuilder => { | ||
const query = queryFromResolveData(sql.identifier(foreignSchema.name, foreignTable.name), foreignTableAlias, resolveData, { asJson: true }, innerQueryBuilder => { | ||
keys.forEach((key, i) => { | ||
@@ -109,0 +103,0 @@ innerQueryBuilder.where(sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(key.name)} = ${foreignTableAlias}.${sql.identifier(foreignKeys[i].name)}`); |
@@ -31,2 +31,6 @@ "use strict"; | ||
var _flatMap = require("lodash/flatMap"); | ||
var _flatMap2 = _interopRequireDefault(_flatMap); | ||
var _package = require("../../package.json"); | ||
@@ -37,2 +41,3 @@ | ||
const debug = (0, _debug2.default)("graphile-build-pg"); | ||
const INTROSPECTION_PATH = `${__dirname}/../../res/introspection-query.sql`; | ||
@@ -56,3 +61,4 @@ const WATCH_FIXTURES_PATH = `${__dirname}/../../res/watch-fixtures.sql`; | ||
persistentMemoizeWithKey = (key, fn) => fn(), | ||
pgThrowOnMissingSchema = false | ||
pgThrowOnMissingSchema = false, | ||
pgIncludeExtensionResources = false | ||
}) { | ||
@@ -74,3 +80,3 @@ async function introspect() { | ||
const introspectionQuery = await readFile(INTROSPECTION_PATH, "utf8"); | ||
const { rows } = await pgClient.query(introspectionQuery, [schemas]); | ||
const { rows } = await pgClient.query(introspectionQuery, [schemas, pgIncludeExtensionResources]); | ||
@@ -86,7 +92,8 @@ const result = rows.reduce((memo, { object }) => { | ||
constraint: [], | ||
procedure: [] | ||
procedure: [], | ||
extension: [] | ||
}); | ||
// Parse tags from comments | ||
["namespace", "class", "attribute", "type", "constraint", "procedure"].forEach(kind => { | ||
["namespace", "class", "attribute", "type", "constraint", "procedure", "extension"].forEach(kind => { | ||
result[kind].forEach(object => { | ||
@@ -103,2 +110,7 @@ if (pgEnableTags && object.description) { | ||
const extensionConfigurationClassIds = (0, _flatMap2.default)(result.extension, e => e.configurationClassIds); | ||
result.class.forEach(klass => { | ||
klass.isExtensionConfigurationTable = extensionConfigurationClassIds.indexOf(klass.id) >= 0; | ||
}); | ||
for (const k in result) { | ||
@@ -134,2 +146,3 @@ result[k].map(Object.freeze); | ||
introspectionResultsByKind.attributeByClassIdAndNum = xByYAndZ(introspectionResultsByKind.attribute, "classId", "num"); | ||
introspectionResultsByKind.extensionById = xByY(introspectionResultsByKind.extension, "id"); | ||
@@ -139,10 +152,23 @@ const relate = (array, newAttr, lookupAttr, lookup, missingOk = false) => { | ||
const key = entry[lookupAttr]; | ||
const result = lookup[key]; | ||
if (key && !result) { | ||
if (missingOk) { | ||
return; | ||
if (Array.isArray(key)) { | ||
entry[newAttr] = key.map(innerKey => { | ||
const result = lookup[innerKey]; | ||
if (innerKey && !result) { | ||
if (missingOk) { | ||
return; | ||
} | ||
throw new Error(`Could not look up '${newAttr}' by '${lookupAttr}' ('${innerKey}') on '${JSON.stringify(entry)}'`); | ||
} | ||
return result; | ||
}).filter(_ => _); | ||
} else { | ||
const result = lookup[key]; | ||
if (key && !result) { | ||
if (missingOk) { | ||
return; | ||
} | ||
throw new Error(`Could not look up '${newAttr}' by '${lookupAttr}' on '${JSON.stringify(entry)}'`); | ||
} | ||
throw new Error(`Could not look up '${newAttr}' by '${lookupAttr}' on '${JSON.stringify(entry)}'`); | ||
entry[newAttr] = result; | ||
} | ||
entry[newAttr] = result; | ||
}); | ||
@@ -170,2 +196,12 @@ }; | ||
relate(introspectionResultsByKind.extension, "namespace", "namespaceId", introspectionResultsByKind.namespaceById, true // Because the extension could be a defined in a different namespace | ||
); | ||
relate(introspectionResultsByKind.extension, "configurationClasses", "configurationClassIds", introspectionResultsByKind.classById, true // Because the configuration table could be a defined in a different namespace | ||
); | ||
introspectionResultsByKind.class.forEach(klass => { | ||
klass.attributes = introspectionResultsByKind.attribute.filter(attr => attr.classId === klass.id); | ||
}); | ||
return introspectionResultsByKind; | ||
@@ -172,0 +208,0 @@ } |
@@ -9,8 +9,2 @@ "use strict"; | ||
var _parseIdentifier = require("../parseIdentifier"); | ||
var _parseIdentifier2 = _interopRequireDefault(_parseIdentifier); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function PgJWTPlugin(builder, { pgJwtTypeIdentifier, pgJwtSecret }) { | ||
@@ -26,3 +20,4 @@ builder.hook("init", (_, build) => { | ||
graphql: { GraphQLScalarType }, | ||
inflection | ||
inflection, | ||
pgParseIdentifier: parseIdentifier | ||
} = build; | ||
@@ -35,3 +30,3 @@ if (!pgJwtTypeIdentifier) { | ||
} | ||
const { namespaceName, entityName: typeName } = (0, _parseIdentifier2.default)(pgJwtTypeIdentifier); | ||
const { namespaceName, entityName: typeName } = parseIdentifier(pgJwtTypeIdentifier); | ||
@@ -38,0 +33,0 @@ const compositeClass = introspectionResultsByKind.class.find(table => !table.isSelectable && !table.isInsertable && !table.isUpdatable && !table.isDeletable && table.name === typeName && table.namespaceName === namespaceName); |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _debug = require("debug"); | ||
@@ -16,10 +12,2 @@ | ||
var _viaTemporaryTable = require("./viaTemporaryTable"); | ||
var _viaTemporaryTable2 = _interopRequireDefault(_viaTemporaryTable); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -39,4 +27,4 @@ | ||
pgIntrospectionResultsByKind, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
pgSql: sql, | ||
@@ -51,3 +39,6 @@ gql2pg, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit, | ||
pgViaTemporaryTable: viaTemporaryTable | ||
} = build; | ||
@@ -59,4 +50,4 @@ const { scope: { isRootMutation }, fieldWithHooks } = context; | ||
return extend(fields, pgIntrospectionResultsByKind.class.filter(table => !!table.namespace).filter(table => table.isSelectable).filter(table => table.isInsertable && !(0, _omit2.default)(table, "create")).reduce((memo, table) => { | ||
const Table = pgGetGqlTypeByTypeId(table.type.id); | ||
return extend(fields, pgIntrospectionResultsByKind.class.filter(table => !!table.namespace).filter(table => table.isSelectable).filter(table => table.isInsertable && !omit(table, "create")).reduce((memo, table) => { | ||
const Table = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
if (!Table) { | ||
@@ -66,6 +57,5 @@ debug(`There was no table type for table '${table.namespace.name}.${table.name}', so we're not generating a create mutation for it.`); | ||
} | ||
const TableInput = pgGetGqlInputTypeByTypeId(table.type.id); | ||
const TableInput = pgGetGqlInputTypeByTypeIdAndModifier(table.type.id, null); | ||
if (!TableInput) { | ||
debug(`There was no input type for table '${table.namespace.name}.${table.name}', so we're not generating a create mutation for it.`); | ||
return memo; | ||
debug(`There was no input type for table '${table.namespace.name}.${table.name}', so we're going to omit it from the create mutation.`); | ||
} | ||
@@ -81,6 +71,8 @@ const tableTypeName = inflection.tableType(table); | ||
}, | ||
[inflection.tableFieldName(table)]: { | ||
description: `The \`${tableTypeName}\` to be created by this mutation.`, | ||
type: new GraphQLNonNull(TableInput) | ||
} | ||
...(TableInput ? { | ||
[inflection.tableFieldName(table)]: { | ||
description: `The \`${tableTypeName}\` to be created by this mutation.`, | ||
type: new GraphQLNonNull(TableInput) | ||
} | ||
} : null) | ||
} | ||
@@ -131,7 +123,7 @@ }, { | ||
const insertedRowAlias = sql.identifier(Symbol()); | ||
const query = (0, _queryFromResolveData2.default)(insertedRowAlias, insertedRowAlias, resolveData, {}); | ||
const query = queryFromResolveData(insertedRowAlias, insertedRowAlias, resolveData, {}); | ||
const sqlColumns = []; | ||
const sqlValues = []; | ||
const inputData = input[inflection.tableFieldName(table)]; | ||
pgIntrospectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !(0, _omit2.default)(attr, "create")).forEach(attr => { | ||
pgIntrospectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).filter(attr => !omit(attr, "create")).forEach(attr => { | ||
const fieldName = inflection.column(attr); | ||
@@ -153,3 +145,3 @@ const val = inputData[fieldName]; | ||
await pgClient.query("SAVEPOINT graphql_mutation"); | ||
const rows = await (0, _viaTemporaryTable2.default)(pgClient, sql.identifier(table.namespace.name, table.name), mutationQuery, insertedRowAlias, query); | ||
const rows = await viaTemporaryTable(pgClient, sql.identifier(table.namespace.name, table.name), mutationQuery, insertedRowAlias, query); | ||
row = rows[0]; | ||
@@ -156,0 +148,0 @@ await pgClient.query("RELEASE SAVEPOINT graphql_mutation"); |
@@ -11,6 +11,2 @@ "use strict"; | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -23,7 +19,8 @@ | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgSql: sql, | ||
graphql: { GraphQLList, GraphQLNonNull }, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
@@ -37,6 +34,6 @@ const { | ||
const table = pgIntrospectionTable || pgIntrospection; | ||
if (!isMutationPayload || !table || table.kind !== "class" || !table.namespace || !table.isSelectable || (0, _omit2.default)(table, "all") && (0, _omit2.default)(table, "many")) { | ||
if (!isMutationPayload || !table || table.kind !== "class" || !table.namespace || !table.isSelectable || omit(table, "all") && omit(table, "many")) { | ||
return fields; | ||
} | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const tableTypeName = TableType.name; | ||
@@ -52,3 +49,3 @@ const TableOrderByType = getTypeByName(inflection.orderByType(tableTypeName)); | ||
const primaryKeys = primaryKeyConstraint && primaryKeyConstraint.keyAttributeNums.map(num => attributes.filter(attr => attr.num === num)[0]); | ||
const canOrderBy = !(0, _omit2.default)(table, "order"); | ||
const canOrderBy = !omit(table, "order"); | ||
@@ -55,0 +52,0 @@ const fieldName = inflection.edgeField(table); |
@@ -7,12 +7,2 @@ "use strict"; | ||
var _makeProcField = require("./makeProcField"); | ||
var _makeProcField2 = _interopRequireDefault(_makeProcField); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function PgMutationProceduresPlugin(builder) { | ||
@@ -23,3 +13,6 @@ builder.hook("GraphQLObjectType:fields", (fields, build, context) => { | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
inflection | ||
inflection, | ||
pgMakeProcField: makeProcField, | ||
pgOmit: omit, | ||
swallowError | ||
} = build; | ||
@@ -30,3 +23,3 @@ const { scope: { isRootMutation }, fieldWithHooks } = context; | ||
} | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => !proc.isStable).filter(proc => !!proc.namespace).filter(proc => !(0, _omit2.default)(proc, "execute")).reduce((memo, proc) => { | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => !proc.isStable).filter(proc => !!proc.namespace).filter(proc => !omit(proc, "execute")).reduce((memo, proc) => { | ||
/* | ||
@@ -48,6 +41,10 @@ proc = | ||
const fieldName = inflection.functionMutationName(proc); | ||
memo[fieldName] = (0, _makeProcField2.default)(fieldName, proc, build, { | ||
fieldWithHooks, | ||
isMutation: true | ||
}); | ||
try { | ||
memo[fieldName] = makeProcField(fieldName, proc, build, { | ||
fieldWithHooks, | ||
isMutation: true | ||
}); | ||
} catch (e) { | ||
swallowError(e); | ||
} | ||
return memo; | ||
@@ -54,0 +51,0 @@ }, {}), `Adding mutation procedure to root Mutation field`); |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _debug = require("debug"); | ||
@@ -16,14 +12,5 @@ | ||
var _viaTemporaryTable = require("./viaTemporaryTable"); | ||
var _viaTemporaryTable2 = _interopRequireDefault(_viaTemporaryTable); | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const debug = (0, _debug2.default)("graphile-build-pg"); | ||
const base64Decode = str => new Buffer(String(str), "base64").toString("utf8"); | ||
@@ -45,4 +32,4 @@ | ||
gql2pg, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
@@ -59,3 +46,6 @@ pgSql: sql, | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit, | ||
pgViaTemporaryTable: viaTemporaryTable | ||
} = build; | ||
@@ -67,4 +57,7 @@ const { scope: { isRootMutation }, fieldWithHooks } = context; | ||
} | ||
return extend(fields, ["update", "delete"].reduce((outerMemo, mode) => introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => mode === "update" && table.isUpdatable && !(0, _omit2.default)(table, "update") || mode === "delete" && table.isDeletable && !(0, _omit2.default)(table, "delete")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
return extend(fields, ["update", "delete"].reduce((outerMemo, mode) => introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => mode === "update" && table.isUpdatable && !omit(table, "update") || mode === "delete" && table.isDeletable && !omit(table, "delete")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
if (!TableType) { | ||
return memo; | ||
} | ||
async function commonCodeRenameMe(pgClient, resolveInfo, getDataFromParsedResolveInfoFragment, PayloadType, input, condition, context) { | ||
@@ -105,7 +98,7 @@ const parsedResolveInfoFragment = parseResolveInfo(resolveInfo); | ||
const modifiedRowAlias = sql.identifier(Symbol()); | ||
const query = (0, _queryFromResolveData2.default)(modifiedRowAlias, modifiedRowAlias, resolveData, {}); | ||
const query = queryFromResolveData(modifiedRowAlias, modifiedRowAlias, resolveData, {}); | ||
let row; | ||
try { | ||
await pgClient.query("SAVEPOINT graphql_mutation"); | ||
const rows = await (0, _viaTemporaryTable2.default)(pgClient, sqlTypeIdentifier, sqlMutationQuery, modifiedRowAlias, query); | ||
const rows = await viaTemporaryTable(pgClient, sqlTypeIdentifier, sqlMutationQuery, modifiedRowAlias, query); | ||
row = rows[0]; | ||
@@ -128,3 +121,3 @@ await pgClient.query("RELEASE SAVEPOINT graphql_mutation"); | ||
const attributes = introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).sort((a, b) => a.num - b.num); | ||
const Table = pgGetGqlTypeByTypeId(table.type.id); | ||
const Table = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const tableTypeName = Table.name; | ||
@@ -254,3 +247,3 @@ const TablePatch = getTypeByName(inflection.patchType(Table.name)); | ||
uniqueConstraints.forEach(constraint => { | ||
if ((0, _omit2.default)(constraint, mode)) { | ||
if (omit(constraint, mode)) { | ||
return; | ||
@@ -262,3 +255,3 @@ } | ||
} | ||
if (keys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (keys.some(key => omit(key, "read"))) { | ||
return; | ||
@@ -282,3 +275,3 @@ } | ||
description: key.description, | ||
type: new GraphQLNonNull(pgGetGqlInputTypeByTypeId(key.typeId)) | ||
type: new GraphQLNonNull(pgGetGqlInputTypeByTypeIdAndModifier(key.typeId, key.typeModifier)) | ||
}; | ||
@@ -285,0 +278,0 @@ return memo; |
@@ -7,8 +7,2 @@ "use strict"; | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function PgOrderAllColumnsPlugin(builder) { | ||
@@ -20,3 +14,4 @@ builder.hook("GraphQLEnumType:values", (values, build, context) => { | ||
pgColumnFilter, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
@@ -28,3 +23,3 @@ const { scope: { isPgRowSortEnum, pgIntrospection: table } } = context; | ||
return extend(values, introspectionResultsByKind.attribute.filter(attr => attr.classId === table.id).filter(attr => pgColumnFilter(attr, build, context)).reduce((memo, attr) => { | ||
if ((0, _omit2.default)(attr, "order")) { | ||
if (omit(attr, "order")) { | ||
return memo; | ||
@@ -31,0 +26,0 @@ } |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _makeProcField = require("./makeProcField"); | ||
var _makeProcField2 = _interopRequireDefault(_makeProcField); | ||
var _debug = require("debug"); | ||
@@ -20,6 +16,2 @@ | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -36,3 +28,5 @@ | ||
inflection, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
pgMakeProcField: makeProcField, | ||
pgOmit: omit | ||
} = build; | ||
@@ -43,3 +37,3 @@ const { scope: { isRootQuery }, fieldWithHooks } = context; | ||
} | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => proc.isStable).filter(proc => !!proc.namespace).filter(proc => !(0, _omit2.default)(proc, "execute")).reduce((memo, proc) => { | ||
return extend(fields, introspectionResultsByKind.procedure.filter(proc => proc.isStable).filter(proc => !!proc.namespace).filter(proc => !omit(proc, "execute")).reduce((memo, proc) => { | ||
/* | ||
@@ -73,3 +67,3 @@ proc = | ||
try { | ||
memo[fieldName] = (0, _makeProcField2.default)(fieldName, proc, build, { | ||
memo[fieldName] = makeProcField(fieldName, proc, build, { | ||
fieldWithHooks, | ||
@@ -80,3 +74,3 @@ forceList | ||
// eslint-disable-next-line no-console | ||
console.warn(_chalk2.default.bold.yellow(`Failed to add function '${proc.namespace.name}.${proc.name}'; run with 'DEBUG="graphile-build-pg:warn"' to view the error`)); | ||
console.warn(_chalk2.default.bold.yellow(`Failed to add function '${proc.namespace.name}.${proc.name}'${debugWarn.enabled ? "" : `; run with 'DEBUG="graphile-build-pg:warn"' to view the error`}`)); | ||
debugWarn(e); | ||
@@ -83,0 +77,0 @@ } |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _debug = require("debug"); | ||
@@ -16,6 +12,2 @@ | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -30,4 +22,4 @@ | ||
parseResolveInfo, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
gql2pg, | ||
@@ -37,3 +29,5 @@ pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
graphql: { GraphQLNonNull }, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit | ||
} = build; | ||
@@ -44,4 +38,4 @@ const { scope: { isRootQuery }, fieldWithHooks } = context; | ||
} | ||
return extend(fields, introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => !(0, _omit2.default)(table, "read")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
return extend(fields, introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => !omit(table, "read")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const sqlFullTableName = sql.identifier(table.namespace.name, table.name); | ||
@@ -52,7 +46,7 @@ if (TableType) { | ||
uniqueConstraints.forEach(constraint => { | ||
if ((0, _omit2.default)(constraint, "read")) { | ||
if (omit(constraint, "read")) { | ||
return; | ||
} | ||
const keys = constraint.keyAttributeNums.map(num => attributes.filter(attr => attr.num === num)[0]); | ||
if (keys.some(key => (0, _omit2.default)(key, "read"))) { | ||
if (keys.some(key => omit(key, "read"))) { | ||
return; | ||
@@ -68,3 +62,3 @@ } | ||
args: keys.reduce((memo, key) => { | ||
const InputType = pgGetGqlInputTypeByTypeId(key.typeId); | ||
const InputType = pgGetGqlInputTypeByTypeIdAndModifier(key.typeId, key.typeModifier); | ||
if (!InputType) { | ||
@@ -81,3 +75,3 @@ throw new Error(`Could not find input type for key '${key.name}' on type '${TableType.name}'`); | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, TableType); | ||
const query = (0, _queryFromResolveData2.default)(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
const query = queryFromResolveData(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
keys.forEach(key => { | ||
@@ -84,0 +78,0 @@ builder.where(sql.fragment`${builder.getTableAlias()}.${sql.identifier(key.name)} = ${gql2pg(args[inflection.column(key)], key.type)}`); |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _queryFromResolveData = require("../queryFromResolveData"); | ||
var _queryFromResolveData2 = _interopRequireDefault(_queryFromResolveData); | ||
var _debug = require("debug"); | ||
@@ -16,6 +12,2 @@ | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -26,3 +18,3 @@ | ||
exports.default = async function PgRowByUniqueConstraint(builder) { | ||
exports.default = async function PgRowNode(builder) { | ||
builder.hook("GraphQLObjectType", (object, build, context) => { | ||
@@ -33,6 +25,8 @@ const { | ||
pgSql: sql, | ||
gql2pg | ||
gql2pg, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit | ||
} = build; | ||
const { scope: { isPgRowType, pgIntrospection: table } } = context; | ||
if (!isPgRowType || !table.namespace || (0, _omit2.default)(table, "read")) { | ||
if (!isPgRowType || !table.namespace || omit(table, "read")) { | ||
return object; | ||
@@ -51,3 +45,3 @@ } | ||
} | ||
const query = (0, _queryFromResolveData2.default)(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
const query = queryFromResolveData(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
primaryKeys.forEach((key, idx) => { | ||
@@ -70,3 +64,3 @@ builder.where(sql.fragment`${builder.getTableAlias()}.${sql.identifier(key.name)} = ${gql2pg(identifiers[idx], primaryKeys[idx].type)}`); | ||
parseResolveInfo, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgIntrospectionResultsByKind: introspectionResultsByKind, | ||
@@ -77,3 +71,5 @@ pgSql: sql, | ||
graphql: { GraphQLNonNull, GraphQLID }, | ||
inflection | ||
inflection, | ||
pgQueryFromResolveData: queryFromResolveData, | ||
pgOmit: omit | ||
} = build; | ||
@@ -84,4 +80,4 @@ const { scope: { isRootQuery }, fieldWithHooks } = context; | ||
} | ||
return extend(fields, introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => !(0, _omit2.default)(table, "read")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeId(table.type.id); | ||
return extend(fields, introspectionResultsByKind.class.filter(table => !!table.namespace).filter(table => !omit(table, "read")).reduce((memo, table) => { | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(table.type.id, null); | ||
const sqlFullTableName = sql.identifier(table.namespace.name, table.name); | ||
@@ -120,3 +116,3 @@ if (TableType) { | ||
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, TableType); | ||
const query = (0, _queryFromResolveData2.default)(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
const query = queryFromResolveData(sqlFullTableName, undefined, resolveData, {}, builder => { | ||
primaryKeys.forEach((key, idx) => { | ||
@@ -123,0 +119,0 @@ builder.where(sql.fragment`${builder.getTableAlias()}.${sql.identifier(key.name)} = ${gql2pg(identifiers[idx], primaryKeys[idx].type)}`); |
@@ -7,8 +7,2 @@ "use strict"; | ||
var _omit = require("../omit"); | ||
var _omit2 = _interopRequireDefault(_omit); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const base64 = str => new Buffer(String(str)).toString("base64"); | ||
@@ -22,3 +16,3 @@ | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
graphql: { | ||
@@ -30,7 +24,8 @@ GraphQLObjectType, | ||
}, | ||
inflection | ||
inflection, | ||
pgOmit: omit | ||
} = build; | ||
const nullableIf = (condition, Type) => condition ? Type : new GraphQLNonNull(Type); | ||
const Cursor = getTypeByName("Cursor"); | ||
introspectionResultsByKind.procedure.filter(proc => proc.returnsSet).filter(proc => !!proc.namespace).filter(proc => !(0, _omit2.default)(proc, "execute")).forEach(proc => { | ||
introspectionResultsByKind.procedure.filter(proc => proc.returnsSet).filter(proc => !!proc.namespace).filter(proc => !omit(proc, "execute")).forEach(proc => { | ||
const returnType = introspectionResultsByKind.typeById[proc.returnTypeId]; | ||
@@ -42,3 +37,6 @@ const returnTypeTable = introspectionResultsByKind.classById[returnType.classId]; | ||
} | ||
const NodeType = pgGetGqlTypeByTypeId(returnType.id) || GraphQLString; | ||
// TODO: PG10 doesn't support the equivalent of pg_attribute.atttypemod | ||
// on function arguments and return types, however maybe a later | ||
// version of PG will? | ||
const NodeType = pgGetGqlTypeByTypeIdAndModifier(returnType.id, null) || GraphQLString; | ||
const EdgeType = newWithHooks(GraphQLObjectType, { | ||
@@ -45,0 +43,0 @@ name: inflection.scalarFunctionEdge(proc), |
@@ -41,4 +41,4 @@ "use strict"; | ||
getTypeByName, | ||
pgGetGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier, | ||
pgRegisterGqlTypeByTypeId, | ||
@@ -84,3 +84,9 @@ pgRegisterGqlInputTypeByTypeId, | ||
const shouldHaveNodeId = nodeIdFieldName && table.isSelectable && table.namespace && primaryKeys && primaryKeys.length ? true : false; | ||
let TableType; | ||
let TablePatchType; | ||
let TableBaseInputType; | ||
pgRegisterGqlTypeByTypeId(tablePgType.id, cb => { | ||
if (TableType) { | ||
return TableType; | ||
} | ||
if (pg2GqlMapper[tablePgType.id]) { | ||
@@ -90,3 +96,3 @@ // Already handled | ||
} | ||
const TableType = newWithHooks(GraphQLObjectType, { | ||
TableType = newWithHooks(GraphQLObjectType, { | ||
description: table.description || tablePgType.description, | ||
@@ -166,7 +172,12 @@ name: tableTypeName, | ||
} | ||
}); | ||
}, true // If no fields, skip type automatically | ||
); | ||
if (table.isSelectable) { | ||
/* const TablePatchType = */ | ||
newWithHooks(GraphQLInputObjectType, { | ||
// XXX: these don't belong here; but we have to keep them here | ||
// because third-party code depends on `getTypeByName` to find | ||
// them; so we have to register them ahead of time. A better | ||
// approach is to use the modifier to specify the type you need, | ||
// 'patch' or 'base', so they can be registered just in time. | ||
TablePatchType = newWithHooks(GraphQLInputObjectType, { | ||
description: `Represents an update to a \`${tableTypeName}\`. Fields that are set will be updated.`, | ||
@@ -183,4 +194,19 @@ name: inflection.patchType(TableType) | ||
} | ||
}, true // Safe to skip this if no fields support updating | ||
); | ||
TableBaseInputType = newWithHooks(GraphQLInputObjectType, { | ||
description: `An input representation of \`${tableTypeName}\` with nullable fields.`, | ||
name: inflection.baseInputType(TableType) | ||
}, { | ||
pgIntrospection: table, | ||
isPgRowType: table.isSelectable, | ||
isPgCompoundType: !table.isSelectable, | ||
isPgBaseInput: true, | ||
pgAddSubfield(fieldName, _attrName, _type, spec) { | ||
// We don't use this currently | ||
return spec; | ||
} | ||
}); | ||
} | ||
const EdgeType = newWithHooks(GraphQLObjectType, { | ||
@@ -262,5 +288,18 @@ description: `A \`${tableTypeName}\` edge in the connection.`, | ||
}, true); | ||
pgRegisterGqlInputTypeByTypeId(tablePgType.id, () => { | ||
const TableType = pgGetGqlTypeByTypeId(tablePgType.id); | ||
return getTypeByName(inflection.inputType(TableType)); | ||
pgRegisterGqlInputTypeByTypeId(tablePgType.id, (_set, modifier) => { | ||
// This must come first, it triggers creation of all the types | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(tablePgType.id, null); | ||
// This must come after the pgGetGqlTypeByTypeIdAndModifier call | ||
if (modifier === "patch") { | ||
// TODO: v5: move the definition from above down here | ||
return TablePatchType; | ||
} | ||
if (modifier === "base") { | ||
// TODO: v5: move the definition from above down here | ||
return TableBaseInputType; | ||
} | ||
if (TableType) { | ||
return getTypeByName(inflection.inputType(TableType)); | ||
} | ||
return null; | ||
}, true); | ||
@@ -277,8 +316,10 @@ | ||
pgRegisterGqlTypeByTypeId(arrayTablePgType.id, () => { | ||
const TableType = pgGetGqlTypeByTypeId(tablePgType.id); | ||
const TableType = pgGetGqlTypeByTypeIdAndModifier(tablePgType.id, null); | ||
return new GraphQLList(TableType); | ||
}, true); | ||
pgRegisterGqlInputTypeByTypeId(arrayTablePgType.id, () => { | ||
const TableInputType = pgGetGqlInputTypeByTypeId(tablePgType.id); | ||
return new GraphQLList(TableInputType); | ||
pgRegisterGqlInputTypeByTypeId(arrayTablePgType.id, (_set, modifier) => { | ||
const RelevantTableInputType = pgGetGqlInputTypeByTypeIdAndModifier(tablePgType.id, modifier); | ||
if (RelevantTableInputType) { | ||
return new GraphQLList(RelevantTableInputType); | ||
} | ||
}, true); | ||
@@ -285,0 +326,0 @@ } |
@@ -7,6 +7,2 @@ "use strict"; | ||
var _graphql = require("graphql"); | ||
var _language = require("graphql/language"); | ||
var _pg = require("pg"); | ||
@@ -16,2 +12,4 @@ | ||
var _GraphQLJSON2 = _interopRequireDefault(_GraphQLJSON); | ||
var _postgresInterval = require("postgres-interval"); | ||
@@ -32,22 +30,2 @@ | ||
const stringType = (name, description) => new _graphql.GraphQLScalarType({ | ||
name, | ||
description, | ||
serialize: value => String(value), | ||
parseValue: value => String(value), | ||
parseLiteral: ast => { | ||
if (ast.kind !== _language.Kind.STRING) { | ||
throw new Error("Can only parse string values"); | ||
} | ||
return ast.value; | ||
} | ||
}); | ||
/* | ||
const { | ||
GraphQLDate, | ||
GraphQLTime, | ||
GraphQLDateTime, | ||
} = require("graphql-iso-date"); | ||
*/ | ||
const parseCache = (0, _lruCache2.default)(500); | ||
@@ -101,9 +79,29 @@ function parseInterval(str) { | ||
pgSql: sql, | ||
inflection | ||
inflection, | ||
graphql | ||
} = build; | ||
const { | ||
GraphQLNonNull, | ||
GraphQLString, | ||
GraphQLInt, | ||
GraphQLFloat, | ||
GraphQLBoolean, | ||
GraphQLList, | ||
GraphQLEnumType, | ||
GraphQLObjectType, | ||
GraphQLInputObjectType, | ||
GraphQLScalarType, | ||
isInputType, | ||
getNamedType, | ||
Kind | ||
} = graphql; | ||
const gqlTypeByTypeIdGenerator = {}; | ||
const gqlInputTypeByTypeIdGenerator = {}; | ||
const gqlTypeByTypeId = Object.assign({}, build.pgGqlTypeByTypeId); | ||
const gqlInputTypeByTypeId = Object.assign({}, build.pgGqlInputTypeByTypeId); | ||
if (build.pgGqlTypeByTypeId || build.pgGqlInputTypeByTypeId) { | ||
// I don't expect anyone to receive this error, because I don't think anyone uses this interface. | ||
throw new Error("Sorry! This interface is no longer supported because it is not granular enough. It's not hard to port it to the new system - please contact Benjie and he'll walk you through it."); | ||
} | ||
const gqlTypeByTypeIdAndModifier = Object.assign({}, build.pgGqlTypeByTypeIdAndModifier); | ||
const gqlInputTypeByTypeIdAndModifier = Object.assign({}, build.pgGqlInputTypeByTypeIdAndModifier); | ||
const pg2GqlMapper = {}; | ||
@@ -169,27 +167,27 @@ const pg2gql = (val, type) => { | ||
description: "A quantity of seconds. This is the only non-integer field, as all the other fields will dump their overflow into a smaller unit of time. Intervals don’t have a smaller unit than seconds.", | ||
type: _graphql.GraphQLFloat | ||
type: GraphQLFloat | ||
}, | ||
minutes: { | ||
description: "A quantity of minutes.", | ||
type: _graphql.GraphQLInt | ||
type: GraphQLInt | ||
}, | ||
hours: { | ||
description: "A quantity of hours.", | ||
type: _graphql.GraphQLInt | ||
type: GraphQLInt | ||
}, | ||
days: { | ||
description: "A quantity of days.", | ||
type: _graphql.GraphQLInt | ||
type: GraphQLInt | ||
}, | ||
months: { | ||
description: "A quantity of months.", | ||
type: _graphql.GraphQLInt | ||
type: GraphQLInt | ||
}, | ||
years: { | ||
description: "A quantity of years.", | ||
type: _graphql.GraphQLInt | ||
type: GraphQLInt | ||
} | ||
}; | ||
}; | ||
const GQLInterval = new _graphql.GraphQLObjectType({ | ||
const GQLInterval = new GraphQLObjectType({ | ||
name: "Interval", | ||
@@ -201,3 +199,3 @@ description: "An interval of time that has passed where the smallest distinct unit is a second.", | ||
const GQLIntervalInput = new _graphql.GraphQLInputObjectType({ | ||
const GQLIntervalInput = new GraphQLInputObjectType({ | ||
name: "IntervalInput", | ||
@@ -209,6 +207,14 @@ description: "An interval of time that has passed where the smallest distinct unit is a second.", | ||
const pgTypeById = introspectionResultsByKind.type.reduce((memo, type) => { | ||
memo[type.id] = type; | ||
return memo; | ||
}, {}); | ||
const stringType = (name, description) => new GraphQLScalarType({ | ||
name, | ||
description, | ||
serialize: value => String(value), | ||
parseValue: value => String(value), | ||
parseLiteral: ast => { | ||
if (ast.kind !== Kind.STRING) { | ||
throw new Error("Can only parse string values"); | ||
} | ||
return ast.value; | ||
} | ||
}); | ||
@@ -229,2 +235,3 @@ const BigFloat = stringType("BigFloat", "A floating point number that requires more precision than IEEE 754 binary 64"); | ||
const tweakToText = fragment => sql.fragment`(${fragment})::text`; | ||
const pgTweaksByTypeIdAndModifer = {}; | ||
const pgTweaksByTypeId = Object.assign( | ||
@@ -248,3 +255,3 @@ // ::text rawTypes | ||
const categoryLookup = { | ||
B: () => _graphql.GraphQLBoolean, | ||
B: () => GraphQLBoolean, | ||
@@ -258,14 +265,17 @@ // Numbers may be too large for GraphQL/JS to handle, so stringify by | ||
A: type => new _graphql.GraphQLList(enforceGqlTypeByPgType(pgTypeById[type.arrayItemTypeId])) | ||
A: (type, typeModifier) => new GraphQLList(getGqlTypeByTypeIdAndModifier(type.arrayItemTypeId, typeModifier)) | ||
}; | ||
const pgTweakFragmentForType = (fragment, type) => { | ||
const tweaker = pgTweaksByTypeId[type.id]; | ||
const pgTweakFragmentForTypeAndModifier = (fragment, type, typeModifier = null, resolveData) => { | ||
const typeModifierKey = typeModifier != null ? typeModifier : -1; | ||
const tweaker = pgTweaksByTypeIdAndModifer[type.id] && pgTweaksByTypeIdAndModifer[type.id][typeModifierKey] || pgTweaksByTypeId[type.id]; | ||
if (tweaker) { | ||
return tweaker(fragment); | ||
return tweaker(fragment, resolveData); | ||
} else if (type.domainBaseType) { | ||
return pgTweakFragmentForType(fragment, type.domainBaseType); | ||
// TODO: check that domains don't support atttypemod | ||
return pgTweakFragmentForTypeAndModifier(fragment, type.domainBaseType, type.domainBaseTypeModifier, resolveData); | ||
} else if (type.isPgArray) { | ||
const error = new Error("Internal graphile-build-pg error: should not attempt to tweak an array, please process array before tweaking (type: `${type.namespaceName}.${type.name}`)"); | ||
if (process.env.NODE_ENV === "test") { | ||
// This is to ensure that Graphile core does not introduce these problems | ||
throw error; | ||
@@ -291,4 +301,6 @@ } | ||
const { GraphQLJSON, GraphQLJson } = (0, _GraphQLJSON2.default)(graphql); | ||
// pgExtendedTypes might change what types we use for things | ||
const JSONType = pgExtendedTypes ? pgLegacyJsonUuid ? _GraphQLJSON.GraphQLJson : _GraphQLJSON.GraphQLJSON : SimpleJSON; | ||
const JSONType = pgExtendedTypes ? pgLegacyJsonUuid ? GraphQLJson : GraphQLJSON : SimpleJSON; | ||
const UUIDType = SimpleUUID; // GraphQLUUID | ||
@@ -300,21 +312,21 @@ const DateType = SimpleDate; // GraphQLDate | ||
// 'point' in PostgreSQL is a 16-byte type that's comprised of two 8-byte floats. | ||
const Point = new _graphql.GraphQLObjectType({ | ||
const Point = new GraphQLObjectType({ | ||
name: "Point", | ||
fields: { | ||
x: { | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) | ||
type: new GraphQLNonNull(GraphQLFloat) | ||
}, | ||
y: { | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) | ||
type: new GraphQLNonNull(GraphQLFloat) | ||
} | ||
} | ||
}); | ||
const PointInput = new _graphql.GraphQLInputObjectType({ | ||
const PointInput = new GraphQLInputObjectType({ | ||
name: "PointInput", | ||
fields: { | ||
x: { | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) | ||
type: new GraphQLNonNull(GraphQLFloat) | ||
}, | ||
y: { | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) | ||
type: new GraphQLNonNull(GraphQLFloat) | ||
} | ||
@@ -333,8 +345,8 @@ } | ||
"20": stringType("BigInt", "A signed eight-byte integer. The upper big integer values are greater then the max value for a JavaScript number. Therefore all big integers will be output as strings and not numbers."), // bitint - even though this is int8, it's too big for JS int, so cast to string. | ||
"21": _graphql.GraphQLInt, // int2 | ||
"23": _graphql.GraphQLInt, // int4 | ||
"700": _graphql.GraphQLFloat, // float4 | ||
"701": _graphql.GraphQLFloat, // float8 | ||
"21": GraphQLInt, // int2 | ||
"23": GraphQLInt, // int4 | ||
"700": GraphQLFloat, // float4 | ||
"701": GraphQLFloat, // float8 | ||
"1700": BigFloat, // numeric | ||
"790": _graphql.GraphQLFloat, // money | ||
"790": GraphQLFloat, // money | ||
@@ -355,5 +367,5 @@ "1186": GQLInterval, // interval | ||
"18": _graphql.GraphQLString, // char | ||
"25": _graphql.GraphQLString, // text | ||
"1043": _graphql.GraphQLString, // varchar | ||
"18": GraphQLString, // char | ||
"25": GraphQLString, // text | ||
"1043": GraphQLString, // varchar | ||
@@ -426,3 +438,10 @@ "600": Point // point | ||
let depth = 0; | ||
const enforceGqlTypeByPgType = type => { | ||
/* | ||
* Enforce: this is the fallback when we can't find a specific GraphQL type | ||
* for a specific PG type. Use the generators from | ||
* `pgRegisterGqlTypeByTypeId` first, this is a last resort. | ||
*/ | ||
const enforceGqlTypeByPgTypeId = (typeId, typeModifier) => { | ||
const type = introspectionResultsByKind.type.find(t => t.id === typeId); | ||
depth++; | ||
@@ -433,3 +452,3 @@ if (depth > 50) { | ||
try { | ||
return reallyEnforceGqlTypeByPgType(type); | ||
return reallyEnforceGqlTypeByPgTypeAndModifier(type, typeModifier); | ||
} catch (e) { | ||
@@ -444,22 +463,29 @@ const error = new Error(`Error occurred when processing database type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`); | ||
}; | ||
const reallyEnforceGqlTypeByPgType = type => { | ||
const reallyEnforceGqlTypeByPgTypeAndModifier = (type, typeModifier) => { | ||
if (!type.id) { | ||
throw new Error(`Invalid argument to enforceGqlTypeByPgType - expected a full type, received '${type}'`); | ||
throw new Error(`Invalid argument to enforceGqlTypeByPgTypeId - expected a full type, received '${type}'`); | ||
} | ||
if (!gqlTypeByTypeIdAndModifier[type.id]) { | ||
gqlTypeByTypeIdAndModifier[type.id] = {}; | ||
} | ||
if (!gqlInputTypeByTypeIdAndModifier[type.id]) { | ||
gqlInputTypeByTypeIdAndModifier[type.id] = {}; | ||
} | ||
const typeModifierKey = typeModifier != null ? typeModifier : -1; | ||
// Explicit overrides | ||
if (!gqlTypeByTypeId[type.id]) { | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]) { | ||
const gqlType = oidLookup[type.id]; | ||
if (gqlType) { | ||
gqlTypeByTypeId[type.id] = gqlType; | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlType; | ||
} | ||
} | ||
if (!gqlInputTypeByTypeId[type.id]) { | ||
if (!gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey]) { | ||
const gqlInputType = oidInputLookup[type.id]; | ||
if (gqlInputType) { | ||
gqlInputTypeByTypeId[type.id] = gqlInputType; | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlInputType; | ||
} | ||
} | ||
// Enums | ||
if (!gqlTypeByTypeId[type.id] && type.type === "e") { | ||
gqlTypeByTypeId[type.id] = new _graphql.GraphQLEnumType({ | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "e") { | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = new GraphQLEnumType({ | ||
name: inflection.enumType(type), | ||
@@ -476,5 +502,5 @@ description: type.description, | ||
// Ranges | ||
if (!gqlTypeByTypeId[type.id] && type.type === "r") { | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "r") { | ||
const subtype = introspectionResultsByKind.typeById[type.rangeSubTypeId]; | ||
const gqlRangeSubType = enforceGqlTypeByPgType(subtype); | ||
const gqlRangeSubType = getGqlTypeByTypeIdAndModifier(subtype.id, typeModifier); | ||
if (!gqlRangeSubType) { | ||
@@ -486,3 +512,3 @@ throw new Error("Range of unsupported"); | ||
if (!Range) { | ||
const RangeBound = new _graphql.GraphQLObjectType({ | ||
const RangeBound = new GraphQLObjectType({ | ||
name: inflection.rangeBoundType(gqlRangeSubType.name), | ||
@@ -493,11 +519,11 @@ description: "The value at one end of a range. A range can either include this value, or not.", | ||
description: "The value at one end of our range.", | ||
type: new _graphql.GraphQLNonNull(gqlRangeSubType) | ||
type: new GraphQLNonNull(gqlRangeSubType) | ||
}, | ||
inclusive: { | ||
description: "Whether or not the value of this bound is included in the range.", | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) | ||
type: new GraphQLNonNull(GraphQLBoolean) | ||
} | ||
} | ||
}); | ||
const RangeBoundInput = new _graphql.GraphQLInputObjectType({ | ||
const RangeBoundInput = new GraphQLInputObjectType({ | ||
name: inflection.inputType(RangeBound.name), | ||
@@ -508,11 +534,11 @@ description: "The value at one end of a range. A range can either include this value, or not.", | ||
description: "The value at one end of our range.", | ||
type: new _graphql.GraphQLNonNull(gqlRangeSubType) | ||
type: new GraphQLNonNull(gqlRangeSubType) | ||
}, | ||
inclusive: { | ||
description: "Whether or not the value of this bound is included in the range.", | ||
type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) | ||
type: new GraphQLNonNull(GraphQLBoolean) | ||
} | ||
} | ||
}); | ||
Range = new _graphql.GraphQLObjectType({ | ||
Range = new GraphQLObjectType({ | ||
name: inflection.rangeType(gqlRangeSubType.name), | ||
@@ -531,3 +557,3 @@ description: `A range of \`${gqlRangeSubType.name}\`.`, | ||
}); | ||
RangeInput = new _graphql.GraphQLInputObjectType({ | ||
RangeInput = new GraphQLInputObjectType({ | ||
name: inflection.inputType(Range.name), | ||
@@ -551,4 +577,4 @@ description: `A range of \`${gqlRangeSubType.name}\`.`, | ||
} | ||
gqlTypeByTypeId[type.id] = Range; | ||
gqlInputTypeByTypeId[type.id] = RangeInput; | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Range; | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = RangeInput; | ||
pg2GqlMapper[type.id] = { | ||
@@ -585,7 +611,7 @@ map: pgRange => { | ||
// Domains | ||
if (!gqlTypeByTypeId[type.id] && type.type === "d" && type.domainBaseTypeId) { | ||
const baseType = enforceGqlTypeByPgType(type.domainBaseType); | ||
const baseInputType = gqlInputTypeByTypeId[type.domainBaseTypeId]; | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "d" && type.domainBaseTypeId) { | ||
const baseType = getGqlTypeByTypeIdAndModifier(type.domainBaseTypeId, typeModifier); | ||
const baseInputType = gqlInputTypeByTypeIdAndModifier[type.domainBaseTypeId][typeModifierKey]; | ||
// Hack stolen from: https://github.com/graphile/postgraphile/blob/ade728ed8f8e3ecdc5fdad7d770c67aa573578eb/src/graphql/schema/type/aliasGqlType.ts#L16 | ||
gqlTypeByTypeId[type.id] = Object.assign(Object.create(baseType), { | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Object.assign(Object.create(baseType), { | ||
name: inflection.domainType(type), | ||
@@ -595,4 +621,4 @@ description: type.description | ||
if (baseInputType && baseInputType !== baseType) { | ||
gqlInputTypeByTypeId[type.id] = Object.assign(Object.create(baseInputType), { | ||
name: inflection.inputType(gqlTypeByTypeId[type.id]), | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = Object.assign(Object.create(baseInputType), { | ||
name: inflection.inputType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]), | ||
description: type.description | ||
@@ -604,6 +630,6 @@ }); | ||
// Fall back to categories | ||
if (!gqlTypeByTypeId[type.id]) { | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]) { | ||
const gen = categoryLookup[type.category]; | ||
if (gen) { | ||
gqlTypeByTypeId[type.id] = gen(type); | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = gen(type, typeModifier); | ||
} | ||
@@ -613,22 +639,25 @@ } | ||
// Nothing else worked; pass through as string! | ||
if (!gqlTypeByTypeId[type.id]) { | ||
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]) { | ||
// XXX: consider using stringType(upperFirst(camelCase(`fallback_${type.name}`)), type.description)? | ||
gqlTypeByTypeId[type.id] = _graphql.GraphQLString; | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = GraphQLString; | ||
} | ||
// Now for input types, fall back to output types if possible | ||
if (!gqlInputTypeByTypeId[type.id]) { | ||
if ((0, _graphql.isInputType)(gqlTypeByTypeId[type.id])) { | ||
gqlInputTypeByTypeId[type.id] = gqlTypeByTypeId[type.id]; | ||
if (!gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey]) { | ||
if (isInputType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey])) { | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]; | ||
} | ||
} | ||
addType((0, _graphql.getNamedType)(gqlTypeByTypeId[type.id])); | ||
return gqlTypeByTypeId[type.id]; | ||
addType(getNamedType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey])); | ||
return gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]; | ||
}; | ||
function getGqlTypeByTypeId(typeId) { | ||
if (!gqlInputTypeByTypeIdGenerator[typeId]) { | ||
const type = introspectionResultsByKind.type.find(t => t.id === typeId); | ||
return enforceGqlTypeByPgType(type); | ||
function getGqlTypeByTypeIdAndModifier(typeId, typeModifier = null, useFallback = true) { | ||
const typeModifierKey = typeModifier != null ? typeModifier : -1; | ||
if (!gqlTypeByTypeIdAndModifier[typeId]) { | ||
gqlTypeByTypeIdAndModifier[typeId] = {}; | ||
} | ||
if (!gqlTypeByTypeId[typeId]) { | ||
if (!gqlInputTypeByTypeIdAndModifier[typeId]) { | ||
gqlInputTypeByTypeIdAndModifier[typeId] = {}; | ||
} | ||
if (!gqlTypeByTypeIdAndModifier[typeId][typeModifierKey]) { | ||
const type = introspectionResultsByKind.type.find(t => t.id === typeId); | ||
@@ -641,24 +670,38 @@ if (!type) { | ||
const set = Type => { | ||
gqlTypeByTypeId[type.id] = Type; | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Type; | ||
}; | ||
const result = gen(set); | ||
const result = gen(set, typeModifier); | ||
if (result) { | ||
if (gqlTypeByTypeId[type.id] && gqlTypeByTypeId[type.id] !== result) { | ||
if (gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] !== result) { | ||
throw new Error(`Callback and return types differ when defining type for '${type.id}'`); | ||
} | ||
gqlTypeByTypeId[type.id] = result; | ||
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = result; | ||
} | ||
} | ||
} | ||
return gqlTypeByTypeId[typeId]; | ||
if (!gqlTypeByTypeIdAndModifier[typeId][typeModifierKey] && typeModifierKey > -1) { | ||
// Fall back to `null` modifier, but if that still doesn't work, we | ||
// still want to pass the modifier to enforceGqlTypeByPgTypeId. | ||
const fallback = getGqlTypeByTypeIdAndModifier(typeId, null, false); | ||
if (fallback) { | ||
return fallback; | ||
} | ||
} | ||
if (useFallback && !gqlTypeByTypeIdAndModifier[typeId][typeModifierKey]) { | ||
return enforceGqlTypeByPgTypeId(typeId, typeModifier); | ||
} | ||
return gqlTypeByTypeIdAndModifier[typeId][typeModifierKey]; | ||
} | ||
function getGqlInputTypeByTypeId(typeId) { | ||
if (!gqlInputTypeByTypeIdGenerator[typeId]) { | ||
const type = introspectionResultsByKind.type.find(t => t.id === typeId); | ||
enforceGqlTypeByPgType(type); | ||
return gqlInputTypeByTypeId[typeId]; | ||
function getGqlInputTypeByTypeIdAndModifier(typeId, typeModifier = null) { | ||
// First, load the OUTPUT type (it might register an input type) | ||
getGqlTypeByTypeIdAndModifier(typeId, typeModifier); | ||
const typeModifierKey = typeModifier != null ? typeModifier : -1; | ||
if (!gqlInputTypeByTypeIdAndModifier[typeId]) { | ||
gqlInputTypeByTypeIdAndModifier[typeId] = {}; | ||
} | ||
if (!gqlInputTypeByTypeId[typeId]) { | ||
if (!gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey]) { | ||
const type = introspectionResultsByKind.type.find(t => t.id === typeId); | ||
getGqlTypeByTypeId(typeId); | ||
if (!type) { | ||
@@ -670,16 +713,19 @@ throw new Error(`Type '${typeId}' not present in introspection results`); | ||
const set = Type => { | ||
gqlInputTypeByTypeId[type.id] = Type; | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = Type; | ||
}; | ||
const result = gen(set); | ||
const result = gen(set, typeModifier); | ||
if (result) { | ||
if (gqlInputTypeByTypeId[type.id] && gqlInputTypeByTypeId[type.id] !== result) { | ||
if (gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] && gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] !== result) { | ||
throw new Error(`Callback and return types differ when defining type for '${type.id}'`); | ||
} | ||
gqlInputTypeByTypeId[type.id] = result; | ||
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = result; | ||
} | ||
} | ||
} | ||
return gqlInputTypeByTypeId[typeId]; | ||
if (!gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey] && typeModifierKey > -1) { | ||
// Fall back to default | ||
return getGqlInputTypeByTypeIdAndModifier(typeId, null); | ||
} | ||
return gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey]; | ||
} | ||
function registerGqlTypeByTypeId(typeId, gen, yieldToExisting = false) { | ||
@@ -704,12 +750,42 @@ if (gqlTypeByTypeIdGenerator[typeId]) { | ||
// DEPRECATIONS! | ||
function getGqlTypeByTypeId(typeId, typeModifier) { | ||
if (typeModifier === undefined) { | ||
// eslint-disable-next-line no-console | ||
console.warn("DEPRECATION WARNING: getGqlTypeByTypeId should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the second parameter (or null if it's not available)."); | ||
} | ||
return getGqlTypeByTypeIdAndModifier(typeId, typeModifier); | ||
} | ||
function getGqlInputTypeByTypeId(typeId, typeModifier) { | ||
if (typeModifier === undefined) { | ||
// eslint-disable-next-line no-console | ||
console.warn("DEPRECATION WARNING: getGqlInputTypeByTypeId should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the second parameter (or null if it's not available)."); | ||
} | ||
return getGqlInputTypeByTypeIdAndModifier(typeId, typeModifier); | ||
} | ||
function pgTweakFragmentForType(fragment, type, typeModifier, resolveData) { | ||
if (typeModifier === undefined) { | ||
// eslint-disable-next-line no-console | ||
console.warn("DEPRECATION WARNING: pgTweakFragmentForType should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the third parameter (or null if it's not available)."); | ||
} | ||
return pgTweakFragmentForTypeAndModifier(fragment, type, typeModifier, resolveData); | ||
} | ||
// END OF DEPRECATIONS! | ||
return build.extend(build, { | ||
pgRegisterGqlTypeByTypeId: registerGqlTypeByTypeId, | ||
pgRegisterGqlInputTypeByTypeId: registerGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeId: getGqlTypeByTypeId, | ||
pgGetGqlInputTypeByTypeId: getGqlInputTypeByTypeId, | ||
pgGetGqlTypeByTypeIdAndModifier: getGqlTypeByTypeIdAndModifier, | ||
pgGetGqlInputTypeByTypeIdAndModifier: getGqlInputTypeByTypeIdAndModifier, | ||
pg2GqlMapper, | ||
pg2gql, | ||
gql2pg, | ||
pgTweakFragmentForType, | ||
pgTweaksByTypeId | ||
pgTweakFragmentForTypeAndModifier, | ||
pgTweaksByTypeId, | ||
pgTweaksByTypeIdAndModifer, | ||
// DEPRECATED METHODS: | ||
pgGetGqlTypeByTypeId: getGqlTypeByTypeId, // DEPRECATED, replaced by getGqlTypeByTypeIdAndModifier | ||
pgGetGqlInputTypeByTypeId: getGqlInputTypeByTypeId, // DEPRECATED, replaced by getGqlInputTypeByTypeIdAndModifier | ||
pgTweakFragmentForType // DEPRECATED, replaced by pgTweakFragmentForTypeAndModifier | ||
}); | ||
@@ -716,0 +792,0 @@ }); |
{ | ||
"name": "graphile-build-pg", | ||
"version": "4.0.0-rc.1", | ||
"version": "4.0.0-rc.2", | ||
"description": "Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build", | ||
@@ -39,3 +39,3 @@ "main": "node8plus/index.js", | ||
"debug": ">=2 <3", | ||
"graphile-build": "4.0.0-rc.1", | ||
"graphile-build": "4.0.0-rc.2", | ||
"graphql-iso-date": "^3.2.0", | ||
@@ -49,3 +49,2 @@ "jsonwebtoken": "^8.1.1", | ||
"peerDependencies": { | ||
"graphql": ">=0.9 <0.14", | ||
"pg": ">=6.1.0 <8" | ||
@@ -55,2 +54,3 @@ }, | ||
"babel-cli": "^6.24.1", | ||
"eslint_d": "5.3.1", | ||
"flow-copy-source": "^1.2.0", | ||
@@ -57,0 +57,0 @@ "jest": "^20.0.4" |
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
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
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
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
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
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
1051091
10
127
5666
4
+ Addedgraphile-build@4.0.0-rc.2(transitive)
+ Addedgraphql-parse-resolve-info@4.0.0-rc.2(transitive)
- Removedgraphile-build@4.0.0-rc.1(transitive)
- Removedgraphql-parse-resolve-info@4.0.0-rc.1(transitive)
Updatedgraphile-build@4.0.0-rc.2