Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
defaultVisitor(node, visitNode) {
if (node.nodes) {
// Recurse into the child nodes array
node.nodes = node.nodes.map(childNode => visitNode(childNode));
}
return node;
},
}),
};
return result;
}
export class Content extends Relationship.implementation {
constructor(path, { blocks: inputBlocks, ...fieldConfig }, listConfig) {
// To maintain consistency with other types, we grab the sanitised name
// directly from the list.
const { itemQueryName } = listConfig.getListByKey(listConfig.listKey).gqlNames;
// We prefix with `_` here to avoid any possible conflict with a list called
// `ContentType`.
// Including the list name + path to make sure these input types are unique
// to this list+field and don't collide.
const type = `${GQL_TYPE_PREFIX}_${itemQueryName}_${path}`;
// Normalise blocks to always be a tuple with a config object
let blocks = (Array.isArray(inputBlocks) ? inputBlocks : []).map(block =>
Array.isArray(block) ? block : [block, {}]
);
const { Relationship } = require('@keystonejs/fields');
// Set up a fresh mutation state if we're the root mutation
const isRootMutation = !mutationState;
if (isRootMutation) {
mutationState = {
afterChangeStack: [], // post-hook stack
queues: {}, // backlink queues
transaction: {}, // transaction
};
}
// Perform the mutation
const { result, afterHook } = await mutation(mutationState);
// resolve backlinks
await Relationship.resolveBacklinks(context, mutationState);
// Push after-hook onto the stack and resolve all if we're the root.
const { afterChangeStack } = mutationState;
afterChangeStack.push(afterHook);
if (isRootMutation) {
// TODO: Close transaction
// Execute post-hook stack
while (afterChangeStack.length) {
await afterChangeStack.pop()();
}
}
// Return the result of the mutation
return result;
}
blockquote,
heading,
imageContainer as image,
link,
orderedList,
unorderedList,
} from './blocks';
export const Content = {
type: 'Content',
implementation: ContentType,
views: {
Controller: importView('./views/Controller'),
Field: importView('./views/Field'),
Cell: importView('./views/Cell'),
Filter: Text.views.Filter,
},
adapters: {
mongoose: MongoContentInterface,
knex: KnexContentInterface,
},
blocks: {
blockquote,
heading,
image,
link,
orderedList,
unorderedList,
// not exposing list-item since it's only used internally by the other blocks
// not exposing paragraph since it's included by default
},
};
extendGraphQLTypes: [`type Movie { title: String, rating: Int }`],
graphQLReturnType: `[Movie]`,
graphQLReturnFragment: `{
title
rating
}`,
resolver: async () => {
const data = [{ title: 'A movie', rating: 2 }, { title: 'Another movie', rating: 4 }];
return data.map(({ title, rating }) => ({ title, rating }));
},
},
value: {
type: Content,
blocks: [
...(cloudinaryAdapter
? [[CloudinaryImage.blocks.image, { adapter: cloudinaryAdapter }]]
: []),
...(embedAdapter ? [[OEmbed.blocks.oEmbed, { adapter: embedAdapter }]] : []),
...(unsplash.accessKey
? [[Unsplash.blocks.unsplashImage, { attribution: 'KeystoneJS', ...unsplash }]]
: []),
Content.blocks.blockquote,
Content.blocks.orderedList,
Content.blocks.unorderedList,
Content.blocks.link,
Content.blocks.heading,
],
},
},
adminConfig: {
defaultPageSize: 20,
defaultColumns: 'name, status',
graphQLReturnFragment: `{
title
rating
}`,
resolver: async () => {
const data = [{ title: 'A movie', rating: 2 }, { title: 'Another movie', rating: 4 }];
return data.map(({ title, rating }) => ({ title, rating }));
},
},
value: {
type: Content,
blocks: [
...(cloudinaryAdapter
? [[CloudinaryImage.blocks.image, { adapter: cloudinaryAdapter }]]
: []),
...(embedAdapter ? [[OEmbed.blocks.oEmbed, { adapter: embedAdapter }]] : []),
...(unsplash.accessKey
? [[Unsplash.blocks.unsplashImage, { attribution: 'KeystoneJS', ...unsplash }]]
: []),
Content.blocks.blockquote,
Content.blocks.orderedList,
Content.blocks.unorderedList,
Content.blocks.link,
Content.blocks.heading,
],
},
},
adminConfig: {
defaultPageSize: 20,
defaultColumns: 'name, status',
defaultSort: 'name',
},
rating
}`,
resolver: async () => {
const data = [{ title: 'A movie', rating: 2 }, { title: 'Another movie', rating: 4 }];
return data.map(({ title, rating }) => ({ title, rating }));
},
},
value: {
type: Content,
blocks: [
...(cloudinaryAdapter
? [[CloudinaryImage.blocks.image, { adapter: cloudinaryAdapter }]]
: []),
...(embedAdapter ? [[OEmbed.blocks.oEmbed, { adapter: embedAdapter }]] : []),
...(unsplash.accessKey
? [[Unsplash.blocks.unsplashImage, { attribution: 'KeystoneJS', ...unsplash }]]
: []),
Content.blocks.blockquote,
Content.blocks.orderedList,
Content.blocks.unorderedList,
Content.blocks.link,
Content.blocks.heading,
],
},
},
adminConfig: {
defaultPageSize: 20,
defaultColumns: 'name, status',
defaultSort: 'name',
},
labelResolver: async (item, args, context, { schema }) => {
if (item.author) {
blocks: unique(flatMap(this.blocks, block => block.getAdminViews())),
};
}
getGqlAuxTypes({ schemaName }) {
return [...super.getGqlAuxTypes({ schemaName }), ...this.auxList.getGqlTypes({ schemaName })];
}
gqlAuxFieldResolvers({ schemaName }) {
return this.auxList.gqlFieldResolvers({ schemaName });
}
}
export class MongoContentInterface extends Relationship.adapters.mongoose {}
export class KnexContentInterface extends Relationship.adapters.knex {}
return {
...views,
blocks: unique(flatMap(this.blocks, block => block.getAdminViews())),
};
}
getGqlAuxTypes({ schemaName }) {
return [...super.getGqlAuxTypes({ schemaName }), ...this.auxList.getGqlTypes({ schemaName })];
}
gqlAuxFieldResolvers({ schemaName }) {
return this.auxList.gqlFieldResolvers({ schemaName });
}
}
export class MongoContentInterface extends Relationship.adapters.mongoose {}
export class KnexContentInterface extends Relationship.adapters.knex {}