graphile-build-pg
Version:
Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build
580 lines (574 loc) • 26.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.preventEmptyResult = preventEmptyResult;
var sql = _interopRequireWildcard(require("pg-sql2"));
var _package = require("../../package.json");
var _pgField = _interopRequireDefault(require("./pgField"));
var _queryFromResolveDataFactory = _interopRequireDefault(require("../queryFromResolveDataFactory"));
var _addStartEndCursor = _interopRequireDefault(require("./addStartEndCursor"));
var _omit = _interopRequireWildcard(require("../omit"));
var _makeProcField = _interopRequireWildcard(require("./makeProcField"));
var _PgComputedColumnsPlugin = require("./PgComputedColumnsPlugin");
var _parseIdentifier = _interopRequireDefault(require("../parseIdentifier"));
var _viaTemporaryTable = _interopRequireDefault(require("./viaTemporaryTable"));
var _chalk = _interopRequireDefault(require("chalk"));
var _pickBy = _interopRequireDefault(require("lodash/pickBy"));
var _PgLiveProvider = _interopRequireDefault(require("../PgLiveProvider"));
var _pgPrepareAndRun = _interopRequireDefault(require("../pgPrepareAndRun"));
var _debugSql = require("./debugSql");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const defaultPgColumnFilter = (_attr, _build, _context) => true;
const identity = _ => _;
function preventEmptyResult(obj) {
return Object.keys(obj).reduce((memo, key) => {
const fn = obj[key];
memo[key] = function (...args) {
const result = fn.apply(this, args);
if (typeof result !== "string" || result.length === 0) {
const stringifiedArgs = require("util").inspect(args);
throw new Error(`Inflector for '${key}' returned '${String(result)}'; expected non-empty string\n` + `See: https://github.com/graphile/graphile-engine/blob/master/packages/graphile-build-pg/src/plugins/PgBasicsPlugin.js\n` + `Arguments passed to ${key}:\n${stringifiedArgs}`);
}
return result;
};
return memo;
}, {});
}
const omitWithRBACChecks = omit => (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 && !tableEntity.attributes.some(attr => attr.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;
const klass = attributeEntity.class;
// Have we got *any* permissions on the table?
if (klass.aclSelectable || klass.attributes.some(attr => attr.aclSelectable)) {
// Yes; this is a regular table; omit if RBAC permissions tell us to.
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;
}
} else {
// No permissions on the table at all, so normal connections will skip
// over it. Thus we must be being exposed via a security definer function
// or similar, so we should expose all fields except those that are
// explicitly @omit-ed.
}
}
return omit(entity, permission);
};
const omitUnindexed = (omit, hideIndexWarnings) => (entity, permission) => {
if (entity.kind === "attribute" && !entity.isIndexed && (permission === "filter" || permission === "order")) {
return true;
}
if (entity.kind === "constraint" && entity.type === "f" && !entity.isIndexed && permission === "read") {
const klass = entity.class;
if (klass) {
const shouldOutputWarning =
// $FlowFixMe
!entity._omitUnindexedReadWarningGiven && !hideIndexWarnings;
if (shouldOutputWarning) {
// $FlowFixMe
entity._omitUnindexedReadWarningGiven = true;
// eslint-disable-next-line no-console
console.log("%s", `Disabled 'read' permission for ${describePgEntity(entity)} because it isn't indexed. For more information see https://graphile.org/postgraphile/best-practices/ To fix, perform\n\n CREATE INDEX ON ${`"${klass.namespaceName}"."${klass.name}"`}("${entity.keyAttributes.map(a => a.name).join('", "')}");`);
}
}
return true;
}
return omit(entity, permission);
};
function describePgEntity(entity, includeAlias = true) {
const getAlias = !includeAlias ? () => "" : () => {
const tags = (0, _pickBy.default)(entity.tags, (value, key) => key === "name" || key.endsWith("Name"));
if (Object.keys(tags).length) {
return ` (with smart comments: ${_chalk.default.bold(Object.keys(tags).map(t => `@${t} ${tags[t]}`).join(" | "))})`;
}
return "";
};
try {
if (entity.kind === "constraint") {
return `constraint ${_chalk.default.bold(`"${entity.name}"`)} on ${describePgEntity(entity.class, false)}${getAlias()}`;
} else if (entity.kind === "class") {
// see pg_class.relkind https://www.postgresql.org/docs/10/static/catalog-pg-class.html
const kind = {
c: "composite type",
f: "foreign table",
p: "partitioned table",
r: "table",
v: "view",
m: "materialized view"
}[entity.classKind] || "table-like";
return `${kind} ${_chalk.default.bold(`"${entity.namespaceName}"."${entity.name}"`)}${getAlias()}`;
} else if (entity.kind === "procedure") {
return `function ${_chalk.default.bold(`"${entity.namespaceName}"."${entity.name}"(...args...)`)}${getAlias()}`;
} else if (entity.kind === "attribute") {
return `column ${_chalk.default.bold(`"${entity.name}"`)} on ${describePgEntity(entity.class, false)}${getAlias()}`;
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Error occurred while attempting to debug entity:", entity);
// eslint-disable-next-line no-console
console.error(e);
}
return `entity of kind '${entity.kind}' with ${typeof entity.id === "string" ? `oid '${entity.id}'` : ""}`;
}
function sqlCommentByAddingTags(entity, tagsToAdd) {
// NOTE: this function is NOT intended to be SQL safe; it's for
// displaying in error messages. Nonetheless if you find issues with
// SQL compatibility, please send a PR or issue.
// Ref: https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-BACKSLASH-TABLE
const escape = str => str.replace(/['\\\b\f\n\r\t]/g, chr => ({
"\b": "\\b",
"\f": "\\f",
"\n": "\\n",
"\r": "\\r",
"\t": "\\t"
})[chr] || "\\" + chr);
// tagsToAdd is here twice to ensure that the keys in tagsToAdd come first, but that they also "win" any conflicts.
const tags = {
...tagsToAdd,
...entity.tags,
...tagsToAdd
};
const description = entity.description;
const tagsSql = Object.keys(tags).reduce((memo, tag) => {
const tagValue = tags[tag];
const valueArray = Array.isArray(tagValue) ? tagValue : [tagValue];
const highlightOrNot = tag in tagsToAdd ? _chalk.default.bold.green : identity;
valueArray.forEach(value => {
memo.push(highlightOrNot(`@${escape(escape(tag))}${value === true ? "" : " " + escape(escape(value))}`));
});
return memo;
}, []).join("\\n");
const commentValue = `E'${tagsSql}${description ? "\\n" + escape(description) : ""}'`;
let sqlThing;
if (entity.kind === "class") {
const identifier = `"${entity.namespaceName}"."${entity.name}"`;
if (entity.classKind === "r") {
sqlThing = `TABLE ${identifier}`;
} else if (entity.classKind === "v") {
sqlThing = `VIEW ${identifier}`;
} else if (entity.classKind === "m") {
sqlThing = `MATERIALIZED VIEW ${identifier}`;
} else if (entity.classKind === "c") {
sqlThing = `TYPE ${identifier}`;
} else {
sqlThing = `PLEASE_SEND_A_PULL_REQUEST_TO_FIX_THIS ${identifier}`;
}
} else if (entity.kind === "attribute") {
sqlThing = `COLUMN "${entity.class.namespaceName}"."${entity.class.name}"."${entity.name}"`;
} else if (entity.kind === "procedure") {
sqlThing = `FUNCTION "${entity.namespaceName}"."${entity.name}"(...arg types go here...)`;
} else if (entity.kind === "constraint") {
// TODO: TEST!
sqlThing = `CONSTRAINT "${entity.name}" ON "${entity.class.namespaceName}"."${entity.class.name}"`;
} else {
sqlThing = `UNKNOWN_ENTITY_PLEASE_SEND_A_PULL_REQUEST`;
}
return `COMMENT ON ${sqlThing} IS ${commentValue};`;
}
var PgBasicsPlugin = function PgBasicsPlugin(builder, {
pgStrictFunctions = false,
pgColumnFilter = defaultPgColumnFilter,
pgIgnoreRBAC = false,
pgIgnoreIndexes = true,
// TODO:v5: change this to false
pgHideIndexWarnings = false,
pgLegacyJsonUuid = false,
// TODO:v5: remove this
pgAugmentIntrospectionResults
}) {
let pgOmit = _omit.default;
if (!pgIgnoreRBAC) {
pgOmit = omitWithRBACChecks(pgOmit);
}
if (!pgIgnoreIndexes) {
pgOmit = omitUnindexed(pgOmit, pgHideIndexWarnings);
}
builder.hook("build", build => {
build.versions["graphile-build-pg"] = _package.version;
build.liveCoordinator.registerProvider(new _PgLiveProvider.default());
return build.extend(build, {
graphileBuildPgVersion: _package.version,
pgSql: sql,
pgStrictFunctions,
pgColumnFilter,
// TODO:v5: remove this workaround
// BEWARE: this may be overridden in PgIntrospectionPlugin for PG < 9.5
pgQueryFromResolveData: (0, _queryFromResolveDataFactory.default)(),
pgAddStartEndCursor: _addStartEndCursor.default,
pgOmit,
pgMakeProcField: _makeProcField.default,
pgProcFieldDetails: _makeProcField.procFieldDetails,
pgGetComputedColumnDetails: _PgComputedColumnsPlugin.getComputedColumnDetails,
pgParseIdentifier: _parseIdentifier.default,
pgViaTemporaryTable: _viaTemporaryTable.default,
describePgEntity,
pgField: _pgField.default,
sqlCommentByAddingTags,
pgPrepareAndRun: _pgPrepareAndRun.default,
pgAugmentIntrospectionResults,
formatSQLForDebugging: _debugSql.formatSQLForDebugging
});
}, ["PgBasics"]);
builder.hook("inflection", (inflection, build) => {
// TODO:v5: move this to postgraphile-core
const oldBuiltin = inflection.builtin;
inflection.builtin = function (name) {
if (pgLegacyJsonUuid && name === "JSON") return "Json";
if (pgLegacyJsonUuid && name === "UUID") return "Uuid";
return oldBuiltin.call(this, name);
};
return build.extend(inflection, preventEmptyResult({
// These helpers are passed GraphQL type names as strings
conditionType(typeName) {
return this.upperCamelCase(`${typeName}-condition`);
},
inputType(typeName) {
return this.upperCamelCase(`${typeName}-input`);
},
rangeBoundType(typeName) {
return this.upperCamelCase(`${typeName}-range-bound`);
},
rangeType(typeName) {
return this.upperCamelCase(`${typeName}-range`);
},
patchType(typeName) {
return this.upperCamelCase(`${typeName}-patch`);
},
baseInputType(typeName) {
return this.upperCamelCase(`${typeName}-base-input`);
},
patchField(itemName) {
return this.camelCase(`${itemName}-patch`);
},
orderByType(typeName) {
return this.upperCamelCase(`${this.pluralize(typeName)}-order-by`);
},
edge(typeName) {
return this.upperCamelCase(`${this.pluralize(typeName)}-edge`);
},
connection(typeName) {
return this.upperCamelCase(`${this.pluralize(typeName)}-connection`);
},
// These helpers handle overrides via smart comments. They should only
// be used in other inflectors, hence the underscore prefix.
//
// IMPORTANT: do NOT do case transforms here, because detail can be
// lost, e.g.
// `constantCase(camelCase('foo_1')) !== constantCase('foo_1')`
_functionName(proc) {
return this.coerceToGraphQLName(proc.tags.name || proc.name);
},
_typeName(type) {
// 'type' introspection result
return this.coerceToGraphQLName(type.tags.name || type.name);
},
_tableName(table) {
return this.coerceToGraphQLName(table.tags.name || table.type.tags.name || table.name);
},
_singularizedTableName(table) {
return this.singularize(this._tableName(table)).replace(/.(?:(?:[_-]i|I)nput|(?:[_-]p|P)atch)$/, "$&_record");
},
_columnName(attr, _options) {
return this.coerceToGraphQLName(attr.tags.name || attr.name);
},
// From here down, functions are passed database introspection results
enumType(type) {
if (type.tags.enumName) {
return type.tags.enumName;
}
return this.upperCamelCase(this._typeName(type));
},
argument(name, index) {
return this.coerceToGraphQLName(this.camelCase(name || `arg${index}`));
},
orderByEnum(columnName, ascending) {
return this.constantCase(`${columnName}_${ascending ? "asc" : "desc"}`);
},
orderByColumnEnum(attr, ascending) {
const columnName = this._columnName(attr, {
skipRowId: true // Because we messed up 😔
});
return this.orderByEnum(columnName, ascending);
},
orderByComputedColumnEnum(pseudoColumnName, proc, table, ascending) {
const columnName = this.computedColumn(pseudoColumnName, proc, table);
return this.orderByEnum(columnName, ascending);
},
domainType(type) {
return this.upperCamelCase(this._typeName(type));
},
enumName(inValue) {
let value = inValue;
if (value === "") {
return "_EMPTY_";
}
// Some enums use asterisks to signify wildcards - this might be for
// the whole item, or prefixes/suffixes, or even in the middle. This
// is provided on a best efforts basis, if it doesn't suit your
// purposes then please pass a custom inflector as mentioned below.
value = value.replace(/\*/g, "_ASTERISK_").replace(/^(_?)_+ASTERISK/, "$1ASTERISK").replace(/ASTERISK_(_?)_*$/, "ASTERISK$1");
// This is a best efforts replacement for common symbols that you
// might find in enums. Generally we only support enums that are
// alphanumeric, if these replacements don't work for you, you should
// pass a custom inflector that replaces this `enumName` method
// with one of your own chosing.
value = {
// SQL comparison operators
">": "GREATER_THAN",
">=": "GREATER_THAN_OR_EQUAL",
"=": "EQUAL",
"!=": "NOT_EQUAL",
"<>": "DIFFERENT",
"<=": "LESS_THAN_OR_EQUAL",
"<": "LESS_THAN",
// PostgreSQL LIKE shortcuts
"~~": "LIKE",
"~~*": "ILIKE",
"!~~": "NOT_LIKE",
"!~~*": "NOT_ILIKE",
// '~' doesn't necessarily represent regexps, but the three
// operators following it likely do, so we'll use the word TILDE
// in all for consistency.
"~": "TILDE",
"~*": "TILDE_ASTERISK",
"!~": "NOT_TILDE",
"!~*": "NOT_TILDE_ASTERISK",
// A number of other symbols where we're not sure of their
// meaning. We give them common generic names so that they're
// suitable for multiple purposes, e.g. favouring 'PLUS' over
// 'ADDITION' and 'DOT' over 'FULL_STOP'
"%": "PERCENT",
"+": "PLUS",
"-": "MINUS",
"/": "SLASH",
"\\": "BACKSLASH",
_: "UNDERSCORE",
"#": "POUND",
"£": "STERLING",
$: "DOLLAR",
"&": "AMPERSAND",
"@": "AT",
"'": "APOSTROPHE",
'"': "QUOTE",
"`": "BACKTICK",
":": "COLON",
";": "SEMICOLON",
"!": "EXCLAMATION_POINT",
"?": "QUESTION_MARK",
",": "COMMA",
".": "DOT",
"^": "CARET",
"|": "BAR",
"[": "OPEN_BRACKET",
"]": "CLOSE_BRACKET",
"(": "OPEN_PARENTHESIS",
")": "CLOSE_PARENTHESIS",
"{": "OPEN_BRACE",
"}": "CLOSE_BRACE"
}[value] || value;
return value;
},
tableNode(table) {
return this.camelCase(this._singularizedTableName(table));
},
tableFieldName(table) {
return this.camelCase(this._singularizedTableName(table));
},
allRows(table) {
return this.camelCase(`all-${this.pluralize(this._singularizedTableName(table))}`);
},
allRowsSimple(table) {
return this.camelCase(`all-${this.pluralize(this._singularizedTableName(table))}-list`);
},
functionMutationName(proc) {
return this.camelCase(this._functionName(proc));
},
functionMutationResultFieldName(proc, gqlType, plural = false, outputArgNames = []) {
if (proc.tags.resultFieldName) {
return proc.tags.resultFieldName;
}
let name;
if (outputArgNames.length === 1 && outputArgNames[0] !== "") {
name = this.camelCase(outputArgNames[0]);
} else if (gqlType.name === "Int") {
name = "integer";
} else if (gqlType.name === "Float") {
name = "float";
} else if (gqlType.name === "Boolean") {
name = "boolean";
} else if (gqlType.name === "String") {
name = "string";
} else if (proc.returnTypeId === "2249") {
// returns a record type
name = "result";
} else {
name = this.camelCase(gqlType.name);
}
return plural ? this.pluralize(name) : name;
},
functionQueryName(proc) {
return this.camelCase(this._functionName(proc));
},
functionQueryNameList(proc) {
return this.camelCase(`${this._functionName(proc)}-list`);
},
functionPayloadType(proc) {
return this.upperCamelCase(`${this._functionName(proc)}-payload`);
},
functionInputType(proc) {
return this.upperCamelCase(`${this._functionName(proc)}-input`);
},
functionOutputFieldName(proc, outputArgName, index) {
return this.argument(outputArgName, index);
},
tableType(table) {
return this.upperCamelCase(this._singularizedTableName(table));
},
column(attr) {
return this.camelCase(this._columnName(attr));
},
computedColumn(pseudoColumnName, proc, _table) {
return proc.tags.fieldName || this.camelCase(pseudoColumnName);
},
computedColumnList(pseudoColumnName, proc, _table) {
return proc.tags.fieldName ? proc.tags.fieldName + "List" : this.camelCase(`${pseudoColumnName}-list`);
},
singleRelationByKeys(detailedKeys, table, _foreignTable, constraint) {
if (constraint.tags.fieldName) {
return constraint.tags.fieldName;
}
return this.camelCase(`${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}`);
},
singleRelationByKeysBackwards(detailedKeys, table, _foreignTable, constraint) {
if (constraint.tags.foreignSingleFieldName) {
return constraint.tags.foreignSingleFieldName;
}
if (constraint.tags.foreignFieldName) {
return constraint.tags.foreignFieldName;
}
return this.singleRelationByKeys(detailedKeys, table, _foreignTable, constraint);
},
manyRelationByKeys(detailedKeys, table, _foreignTable, constraint) {
if (constraint.tags.foreignFieldName) {
return constraint.tags.foreignFieldName;
}
return this.camelCase(`${this.pluralize(this._singularizedTableName(table))}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}`);
},
manyRelationByKeysSimple(detailedKeys, table, _foreignTable, constraint) {
if (constraint.tags.foreignSimpleFieldName) {
return constraint.tags.foreignSimpleFieldName;
}
if (constraint.tags.foreignFieldName) {
return constraint.tags.foreignFieldName;
}
return this.camelCase(`${this.pluralize(this._singularizedTableName(table))}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}-list`);
},
rowByUniqueKeys(detailedKeys, table, constraint) {
if (constraint.tags.fieldName) {
return constraint.tags.fieldName;
}
return this.camelCase(`${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}`);
},
updateByKeys(detailedKeys, table, constraint) {
if (constraint.tags.updateFieldName) {
return constraint.tags.updateFieldName;
}
return this.camelCase(`update-${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}`);
},
deleteByKeys(detailedKeys, table, constraint) {
if (constraint.tags.deleteFieldName) {
return constraint.tags.deleteFieldName;
}
return this.camelCase(`delete-${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}`);
},
updateByKeysInputType(detailedKeys, table, constraint) {
if (constraint.tags.updateFieldName) {
return this.upperCamelCase(`${constraint.tags.updateFieldName}-input`);
}
return this.upperCamelCase(`update-${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}-input`);
},
deleteByKeysInputType(detailedKeys, table, constraint) {
if (constraint.tags.deleteFieldName) {
return this.upperCamelCase(`${constraint.tags.deleteFieldName}-input`);
}
return this.upperCamelCase(`delete-${this._singularizedTableName(table)}-by-${detailedKeys.map(key => this.column(key)).join("-and-")}-input`);
},
updateNode(table) {
return this.camelCase(`update-${this._singularizedTableName(table)}`);
},
deleteNode(table) {
return this.camelCase(`delete-${this._singularizedTableName(table)}`);
},
deletedNodeId(table) {
return this.camelCase(`deleted-${this.singularize(table.name)}-id`);
},
updateNodeInputType(table) {
return this.upperCamelCase(`update-${this._singularizedTableName(table)}-input`);
},
deleteNodeInputType(table) {
return this.upperCamelCase(`delete-${this._singularizedTableName(table)}-input`);
},
edgeField(table) {
return this.camelCase(`${this._singularizedTableName(table)}-edge`);
},
recordFunctionReturnType(proc) {
return proc.tags.resultTypeName || this.upperCamelCase(`${this._functionName(proc)}-record`);
},
recordFunctionConnection(proc) {
return this.upperCamelCase(`${this._functionName(proc)}-connection`);
},
recordFunctionEdge(proc) {
return this.upperCamelCase(`${this.singularize(this._functionName(proc))}-edge`);
},
scalarFunctionConnection(proc) {
return this.upperCamelCase(`${this._functionName(proc)}-connection`);
},
scalarFunctionEdge(proc) {
return this.upperCamelCase(`${this.singularize(this._functionName(proc))}-edge`);
},
createField(table) {
return this.camelCase(`create-${this._singularizedTableName(table)}`);
},
createInputType(table) {
return this.upperCamelCase(`create-${this._singularizedTableName(table)}-input`);
},
createPayloadType(table) {
return this.upperCamelCase(`create-${this._singularizedTableName(table)}-payload`);
},
updatePayloadType(table) {
return this.upperCamelCase(`update-${this._singularizedTableName(table)}-payload`);
},
deletePayloadType(table) {
return this.upperCamelCase(`delete-${this._singularizedTableName(table)}-payload`);
}
}), "Default inflectors from PgBasicsPlugin. You can override these with `makeAddInflectorsPlugin(..., true)`.");
}, ["PgBasics"]);
};
exports.default = PgBasicsPlugin;
//# sourceMappingURL=PgBasicsPlugin.js.map