Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function graphQlQueryToMongoJoinQuery(query) {
const _query = {
...query.where,
...mapKeyNames(
// Grab all the modifiers
pick(query, ['search', 'orderBy', 'skip', 'first']),
// and prefix with a dollar symbol so they can be picked out by the
// query builder tokeniser
key => `$${key}`
),
};
return mapKeys(_query, field => {
if (getType(field) !== 'Object' || !field.where) {
return field;
}
// recurse on object (ie; relationship) types
return graphQlQueryToMongoJoinQuery(field);
});
}
initFields() {
if (this.fieldsInitialised) return;
this.fieldsInitialised = true;
let sanitisedFieldsConfig = mapKeys(this._fields, (fieldConfig, path) => ({
...fieldConfig,
type: mapNativeTypeToKeystoneType(fieldConfig.type, this.key, path),
}));
// Add an 'id' field if none supplied
if (!sanitisedFieldsConfig.id) {
if (typeof this.adapter.parentAdapter.getDefaultPrimaryKeyConfig !== 'function') {
throw `No 'id' field given for the '${this.key}' list and the list adapter ` +
`in used (${this.adapter.key}) doesn't supply a default primary key config ` +
`(no 'getDefaultPrimaryKeyConfig()' function)`;
}
// Rebuild the object so id is "first"
sanitisedFieldsConfig = {
id: this.adapter.parentAdapter.getDefaultPrimaryKeyConfig(),
...sanitisedFieldsConfig,
};
getAdminMeta({ schemaName }) {
const schemaAccess = this.access[schemaName];
return {
key: this.key,
// Reduce to truthy values (functions can't be passed over the webpack
// boundary)
access: mapKeys(schemaAccess, val => !!val),
label: this.adminUILabels.label,
singular: this.adminUILabels.singular,
plural: this.adminUILabels.plural,
path: this.adminUILabels.path,
gqlNames: this.gqlNames,
fields: this.fields
.filter(field => field.access[schemaName].read)
.map(field => field.getAdminMeta({ schemaName })),
views: this.views,
adminConfig: {
defaultPageSize: this.adminConfig.defaultPageSize,
defaultColumns: this.adminConfig.defaultColumns.replace(/\s/g, ''), // remove all whitespace
defaultSort: this.adminConfig.defaultSort,
maximumPageSize: Math.max(
this.adminConfig.defaultPageSize,
this.adminConfig.maximumPageSize
throw `The '${this.key}.${fieldKey}' field doesn't specify a valid type. ` +
`(${this.key}.${fieldKey}.type is undefined)`;
}
const adapters = fieldConfig.type.adapters;
if (typeof adapters === 'undefined' || Object.entries(adapters).length === 0) {
throw `The type given for the '${this.key}.${fieldKey}' field doesn't define any adapters.`;
}
});
Object.values(sanitisedFieldsConfig).forEach(({ type }) => {
if (!type.adapters[this.adapterName]) {
throw `Adapter type "${this.adapterName}" does not support field type "${type.type}"`;
}
});
this.fieldsByPath = mapKeys(
sanitisedFieldsConfig,
({ type, ...fieldSpec }, path) =>
new type.implementation(path, fieldSpec, {
getListByKey: this.getListByKey,
listKey: this.key,
listAdapter: this.adapter,
fieldAdapterClass: type.adapters[this.adapterName],
defaultAccess: this.defaultAccess.field,
createAuxList: this.createAuxList,
schemaNames: this._schemaNames,
})
);
this.fields = Object.values(this.fieldsByPath);
this.views = mapKeys(sanitisedFieldsConfig, ({ type }, path) =>
this.fieldsByPath[path].extendAdminViews({ ...type.views })
);
async _beforeDelete(existingItem, context, operation) {
const args = {
existingItem,
context,
actions: mapKeys(this.hooksActions, hook => hook(context)),
operation,
};
await this._runHook(args, existingItem, 'beforeDelete');
}
async _resolveDefaults({ existingItem, context, originalInput }) {
const args = {
existingItem,
context,
originalInput,
actions: mapKeys(this.hooksActions, hook => hook(context)),
};
const fieldsWithoutValues = this.fields.filter(
field => typeof originalInput[field.path] === 'undefined'
);
const defaultValues = await this._mapToFields(fieldsWithoutValues, field =>
field.getDefaultValue(args)
);
return {
...omitBy(defaultValues, path => typeof defaultValues[path] === 'undefined'),
...originalInput,
};
}
async _validateDelete(existingItem, context, operation) {
const args = {
existingItem,
context,
actions: mapKeys(this.hooksActions, hook => hook(context)),
operation,
};
const fields = this.fields;
await this._validateHook(args, fields, operation, 'validateDelete');
}
this.fieldsByPath = mapKeys(
sanitisedFieldsConfig,
({ type, ...fieldSpec }, path) =>
new type.implementation(path, fieldSpec, {
getListByKey: this.getListByKey,
listKey: this.key,
listAdapter: this.adapter,
fieldAdapterClass: type.adapters[this.adapterName],
defaultAccess: this.defaultAccess.field,
createAuxList: this.createAuxList,
schemaNames: this._schemaNames,
})
);
this.fields = Object.values(this.fieldsByPath);
this.views = mapKeys(sanitisedFieldsConfig, ({ type }, path) =>
this.fieldsByPath[path].extendAdminViews({ ...type.views })
);
}
async _beforeChange(resolvedData, existingItem, context, operation, originalInput) {
const args = {
resolvedData,
existingItem,
context,
originalInput,
actions: mapKeys(this.hooksActions, hook => hook(context)),
operation,
};
await this._runHook(args, resolvedData, 'beforeChange');
}
async _afterChange(updatedItem, existingItem, context, operation, originalInput) {
const args = {
updatedItem,
originalInput,
existingItem,
context,
actions: mapKeys(this.hooksActions, hook => hook(context)),
operation,
};
await this._runHook(args, updatedItem, 'afterChange');
}