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
113 lines (110 loc) • 3.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.UPDATE = exports.READ = exports.ORDER = exports.MANY = exports.FILTER = exports.EXECUTE = exports.DELETE = exports.CREATE = exports.BASE = exports.ALL = void 0;
exports.default = omit;
/*
* Please only use capitals for aliases and lower case for the values.
*/
const CREATE = "create";
exports.CREATE = CREATE;
const READ = "read";
exports.READ = READ;
const UPDATE = "update";
exports.UPDATE = UPDATE;
const DELETE = "delete";
exports.DELETE = DELETE;
const FILTER = "filter";
exports.FILTER = FILTER;
const ORDER = "order";
exports.ORDER = ORDER;
const ALL = "all";
exports.ALL = ALL;
const MANY = "many";
exports.MANY = MANY;
const EXECUTE = "execute";
exports.EXECUTE = EXECUTE;
const BASE = "base";
exports.BASE = BASE;
const aliases = {
C: CREATE,
R: READ,
U: UPDATE,
D: DELETE,
F: FILTER,
O: ORDER,
A: ALL,
M: MANY,
X: EXECUTE,
B: BASE
};
const PERMISSIONS_THAT_REQUIRE_READ = [UPDATE, CREATE, DELETE, ALL, MANY];
function parse(arrOrNot, errorPrefix = "Error") {
if (!arrOrNot) {
return null;
}
const arr = Array.isArray(arrOrNot) ? arrOrNot : [arrOrNot];
let all = false;
const arrayNormalized = [].concat(...arr.map(str => {
if (str === true || str === "*") {
all = true;
return [];
}
if (str[0] === ":") {
const perms = str.slice(1).split("").map(p => aliases[p]);
const bad = perms.find(p => !p);
if (bad) {
throw new Error(`${errorPrefix} - abbreviated parameter '${bad}' not understood`);
}
return perms;
} else {
const perms = str.split(",");
// TODO: warning if not in list?
return perms;
}
}));
if (all) {
return true;
}
return arrayNormalized;
}
function omit(entity, permission) {
const tags = entity.tags;
const omitSpecRaw = tags.omit;
// '@include' is not being released yet because it would mean every new
// filter we added would become a breaking change for people using @include.
const includeSpecRaw = null;
// const includeSpecRaw = tags.include;
if (omitSpecRaw && includeSpecRaw) {
throw new Error(`Error when processing instructions for ${entity.kind} '${entity.name}' - you must only specify @omit or @include, not both`);
}
const omitSpec = parse(omitSpecRaw, `Error when processing @omit instructions for ${entity.kind} '${entity.name}'`);
const includeSpec = parse(includeSpecRaw, `Error when processing @include instructions for ${entity.kind} '${entity.name}'`);
if (omitSpec) {
if (omitSpec === true) {
return true;
}
if (omitSpec.indexOf(READ) >= 0) {
const bad = PERMISSIONS_THAT_REQUIRE_READ.filter(p => omitSpec.indexOf(p) === -1);
if (bad.length > 0) {
throw new Error(`Processing @omit for ${entity.kind} '${entity.name}' - '${bad.join(",")}' must be omitted when '${READ}' is omitted. Add '${bad.join(",")}' to the @omit clause, or use '@omit' to omit all actions.`);
}
}
return omitSpec.indexOf(permission) >= 0;
} else if (includeSpec) {
if (includeSpec === true) {
throw new Error(`Error when processing instructions for ${entity.kind} '${entity.name}' - @include should specify a list of actions`);
}
if (includeSpec.indexOf(READ) === -1) {
const bad = PERMISSIONS_THAT_REQUIRE_READ.find(p => includeSpec.indexOf(p) >= 0);
if (bad) {
throw new Error(`Error when processing @include for ${entity.kind} '${entity.name}' - we currently don't support '${bad}' when '${READ}' is forbidden`);
}
}
return includeSpec.indexOf(permission) === -1;
} else {
return false;
}
}
//# sourceMappingURL=omit.js.map