mirror of
https://github.com/vale981/Vulcan
synced 2025-03-05 17:41:43 -05:00
Start CRUD renaming
This commit is contained in:
parent
c70f32a52a
commit
96eab44309
11 changed files with 184 additions and 119 deletions
|
@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { IntlProvider, intlShape } from 'meteor/vulcan:i18n';
|
||||
import withCurrentUser from '../containers/withCurrentUser.js';
|
||||
import withEdit from '../containers/withEdit.js';
|
||||
import withUpdate from '../containers/withUpdate.js';
|
||||
import { withApollo } from 'react-apollo';
|
||||
import { withCookies } from 'react-cookie';
|
||||
|
||||
|
@ -50,7 +50,7 @@ class App extends PureComponent {
|
|||
this.props.cookies.set('locale', locale);
|
||||
// if user is logged in, change their `locale` profile property
|
||||
if (this.props.currentUser) {
|
||||
await this.props.editMutation({ documentId: this.props.currentUser._id, set: { locale }});
|
||||
await this.props.updateUser({ documentId: this.props.currentUser._id, set: { locale }});
|
||||
}
|
||||
this.props.client.resetStore()
|
||||
};
|
||||
|
@ -113,11 +113,11 @@ App.childContextTypes = {
|
|||
|
||||
App.displayName = 'App';
|
||||
|
||||
const editOptions = {
|
||||
const updateOptions = {
|
||||
collectionName: 'Users',
|
||||
fragmentName: 'UsersCurrent',
|
||||
}
|
||||
|
||||
registerComponent('App', App, withCurrentUser, [withEdit, editOptions], withApollo, withCookies);
|
||||
registerComponent('App', App, withCurrentUser, [withUpdate, updateOptions], withApollo, withCookies);
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -5,9 +5,9 @@ a related query on the client with the new item and a new total item count.
|
|||
|
||||
Sample mutation:
|
||||
|
||||
mutation moviesNew($document: MoviesInput) {
|
||||
moviesNew(document: $document) {
|
||||
...MoviesNewFormFragment
|
||||
mutation updateMovie($document: MoviesInput) {
|
||||
updateMovie(document: $document) {
|
||||
...MovieFormFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ Arguments:
|
|||
|
||||
Child Props:
|
||||
|
||||
- newMutation(document)
|
||||
- createMovie(document)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -26,14 +26,15 @@ import { graphql } from 'react-apollo';
|
|||
import gql from 'graphql-tag';
|
||||
import { getFragment, getFragmentName, getCollection } from 'meteor/vulcan:core';
|
||||
|
||||
export default function withNew(options) {
|
||||
export default function withCreate(options) {
|
||||
|
||||
const { collectionName } = options;
|
||||
// get options
|
||||
const collection = options.collection || getCollection(collectionName),
|
||||
fragment = options.fragment || getFragment(options.fragmentName),
|
||||
fragmentName = getFragmentName(fragment),
|
||||
mutationName = collection.options.mutations.new.name;
|
||||
mutationName = collection.options.mutations.create.name,
|
||||
typeName = collection.options.typeName;
|
||||
|
||||
// wrap component with graphql HoC
|
||||
return graphql(gql`
|
||||
|
@ -44,8 +45,14 @@ export default function withNew(options) {
|
|||
}
|
||||
${fragment}
|
||||
`, {
|
||||
alias: 'withNew',
|
||||
alias: `withCreate${typeName}`,
|
||||
props: ({ownProps, mutate}) => ({
|
||||
[`create${typeName}`]: ({document}) => {
|
||||
return mutate({
|
||||
variables: { document },
|
||||
});
|
||||
},
|
||||
// OpenCRUD backwards compatibility
|
||||
newMutation: ({document}) => {
|
||||
return mutate({
|
||||
variables: { document },
|
|
@ -4,9 +4,9 @@ Generic mutation wrapper to remove a document from a collection.
|
|||
|
||||
Sample mutation:
|
||||
|
||||
mutation moviesRemove($documentId: String) {
|
||||
moviesEdit(documentId: $documentId) {
|
||||
...MoviesRemoveFormFragment
|
||||
mutation deleteMovie($documentId: String) {
|
||||
deleteMovie(documentId: $documentId) {
|
||||
...MovieFormFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ Arguments:
|
|||
|
||||
Child Props:
|
||||
|
||||
- removeMutation(documentId)
|
||||
- deleteMovie(documentId)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -25,11 +25,12 @@ import { graphql } from 'react-apollo';
|
|||
import gql from 'graphql-tag';
|
||||
import { getCollection } from 'meteor/vulcan:core';
|
||||
|
||||
export default function withRemove(options) {
|
||||
export default function withDelete(options) {
|
||||
|
||||
const { collectionName } = options;
|
||||
const collection = options.collection || getCollection(collectionName),
|
||||
mutationName = collection.options.mutations.remove.name
|
||||
mutationName = collection.options.mutations.delete.name,
|
||||
typeName = collection.options.typeName;
|
||||
|
||||
return graphql(gql`
|
||||
mutation ${mutationName}($documentId: String) {
|
||||
|
@ -38,8 +39,14 @@ export default function withRemove(options) {
|
|||
}
|
||||
}
|
||||
`, {
|
||||
alias: 'withRemove',
|
||||
alias: `withDelete${typeName}`,
|
||||
props: ({ ownProps, mutate }) => ({
|
||||
[`delete${typeName}`]: ({ documentId }) => {
|
||||
return mutate({
|
||||
variables: { documentId }
|
||||
});
|
||||
},
|
||||
// OpenCRUD backwards compatibility
|
||||
removeMutation: ({ documentId }) => {
|
||||
return mutate({
|
||||
variables: { documentId }
|
|
@ -4,9 +4,9 @@ Generic mutation wrapper to edit a document in a collection.
|
|||
|
||||
Sample mutation:
|
||||
|
||||
mutation moviesEdit($documentId: String, $set: MoviesInput, $unset: MoviesUnset) {
|
||||
moviesEdit(documentId: $documentId, set: $set, unset: $unset) {
|
||||
...MoviesEditFormFragment
|
||||
mutation updateMovie($documentId: String, $set: MoviesInput, $unset: MoviesUnset) {
|
||||
updateMovie(documentId: $documentId, set: $set, unset: $unset) {
|
||||
...MovieFormFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ Arguments:
|
|||
|
||||
Child Props:
|
||||
|
||||
- editMutation(documentId, set, unset)
|
||||
- updateMovie(documentId, set, unset)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,14 +27,15 @@ import { graphql } from 'react-apollo';
|
|||
import gql from 'graphql-tag';
|
||||
import { getFragment, getFragmentName, getCollection } from 'meteor/vulcan:lib';
|
||||
|
||||
export default function withEdit(options) {
|
||||
export default function withUpdate(options) {
|
||||
|
||||
const { collectionName } = options;
|
||||
// get options
|
||||
const collection = options.collection || getCollection(collectionName),
|
||||
fragment = options.fragment || getFragment(options.fragmentName),
|
||||
fragmentName = getFragmentName(fragment),
|
||||
mutationName = collection.options.mutations.edit.name;
|
||||
mutationName = collection.options.mutations.update.name,
|
||||
typeName = collection.options.typeName;
|
||||
|
||||
return graphql(gql`
|
||||
mutation ${mutationName}($documentId: String, $set: ${collection.options.collectionName}Input, $unset: ${collection.options.collectionName}Unset) {
|
||||
|
@ -44,8 +45,16 @@ export default function withEdit(options) {
|
|||
}
|
||||
${fragment}
|
||||
`, {
|
||||
alias: 'withEdit',
|
||||
alias: `withUpdate${typeName}`,
|
||||
props: ({ ownProps, mutate }) => ({
|
||||
[`update${typeName}`]: (args) => {
|
||||
const { documentId, set, unset } = args;
|
||||
return mutate({
|
||||
variables: { documentId, set, unset }
|
||||
// note: updateQueries is not needed for editing documents
|
||||
});
|
||||
},
|
||||
// OpenCRUD backwards compatibility
|
||||
editMutation: (args) => {
|
||||
const { documentId, set, unset } = args;
|
||||
return mutate({
|
|
@ -4,23 +4,23 @@ Default mutations
|
|||
|
||||
*/
|
||||
|
||||
import { registerCallback, newMutator, editMutator, removeMutator, Utils, Connectors } from 'meteor/vulcan:lib';
|
||||
import { registerCallback, createMutator, updateMutator, deleteMutator, Utils, Connectors } from 'meteor/vulcan:lib';
|
||||
import Users from 'meteor/vulcan:users';
|
||||
|
||||
export const getDefaultMutations = (collectionName, options = {}) => {
|
||||
export const getDefaultMutations = (typeName, options = { legacy: false }) => {
|
||||
|
||||
// register callbacks for documentation purposes
|
||||
registerCollectionCallbacks(collectionName);
|
||||
registerCollectionCallbacks(typeName);
|
||||
|
||||
return {
|
||||
|
||||
// mutation for inserting a new document
|
||||
|
||||
new: {
|
||||
create: {
|
||||
|
||||
name: `${collectionName}New`,
|
||||
name: options.legacy ? `${typeName}New` : `create${Utils.capitalize(typeName)}`,
|
||||
|
||||
description: `Mutation for inserting new ${collectionName} documents`,
|
||||
description: `Mutation for creating new ${typeName} documents`,
|
||||
|
||||
// check function called on a user to see if they can perform the operation
|
||||
check(user, document) {
|
||||
|
@ -28,18 +28,18 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
return options.newCheck(user, document);
|
||||
}
|
||||
// check if they can perform "foo.new" operation (e.g. "movies.new")
|
||||
return Users.canDo(user, `${collectionName.toLowerCase()}.new`);
|
||||
return Users.canDo(user, `${typeName.toLowerCase()}.new`);
|
||||
},
|
||||
|
||||
async mutation(root, {document}, context) {
|
||||
|
||||
const collection = context[collectionName];
|
||||
const collection = context[typeName];
|
||||
|
||||
// check if current user can pass check function; else throw error
|
||||
Utils.performCheck(this.check, context.currentUser, document);
|
||||
|
||||
// pass document to boilerplate newMutator function
|
||||
return await newMutator({
|
||||
return await createMutator({
|
||||
collection,
|
||||
document: document,
|
||||
currentUser: context.currentUser,
|
||||
|
@ -52,11 +52,11 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
|
||||
// mutation for editing a specific document
|
||||
|
||||
edit: {
|
||||
update: {
|
||||
|
||||
name: `${collectionName}Edit`,
|
||||
name: options.legacy ? `${typeName}Edit` : `update${Utils.capitalize(typeName)}`,
|
||||
|
||||
description: `Mutation for editing a ${collectionName} document`,
|
||||
description: `Mutation for updating a ${typeName} document`,
|
||||
|
||||
// check function called on a user and document to see if they can perform the operation
|
||||
check(user, document) {
|
||||
|
@ -68,12 +68,12 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
// check if user owns the document being edited.
|
||||
// if they do, check if they can perform "foo.edit.own" action
|
||||
// if they don't, check if they can perform "foo.edit.all" action
|
||||
return Users.owns(user, document) ? Users.canDo(user, `${collectionName.toLowerCase()}.edit.own`) : Users.canDo(user, `${collectionName.toLowerCase()}.edit.all`);
|
||||
return Users.owns(user, document) ? Users.canDo(user, `${typeName.toLowerCase()}.edit.own`) : Users.canDo(user, `${typeName.toLowerCase()}.edit.all`);
|
||||
},
|
||||
|
||||
async mutation(root, {documentId, set, unset}, context) {
|
||||
|
||||
const collection = context[collectionName];
|
||||
const collection = context[typeName];
|
||||
|
||||
// get entire unmodified document from database
|
||||
const document = await Connectors.get(collection, documentId);
|
||||
|
@ -82,7 +82,7 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
Utils.performCheck(this.check, context.currentUser, document);
|
||||
|
||||
// call editMutator boilerplate function
|
||||
return await editMutator({
|
||||
return await updateMutator({
|
||||
collection,
|
||||
documentId: documentId,
|
||||
set: set,
|
||||
|
@ -97,12 +97,12 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
|
||||
// mutation for upserting a specific document
|
||||
upsert: {
|
||||
name: `${collectionName}Upsert`,
|
||||
name: options.legacy ? `${typeName}Upsert` : `upsert${Utils.capitalize(typeName)}`,
|
||||
|
||||
description: `Mutation for upserting a ${collectionName} document`,
|
||||
description: `Mutation for upserting a ${typeName} document`,
|
||||
|
||||
async mutation(root, { search, set, unset }, context) {
|
||||
const collection = context[collectionName];
|
||||
const collection = context[typeName];
|
||||
|
||||
// check if document exists already
|
||||
const existingDocument = await Connectors.get(collection, search, { fields: { _id: 1 } });
|
||||
|
@ -113,20 +113,20 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
set,
|
||||
unset,
|
||||
};
|
||||
return await collection.options.mutations.edit.mutation(root, editArgs, context);
|
||||
return await collection.options.mutations.update.mutation(root, editArgs, context);
|
||||
} else {
|
||||
return await collection.options.mutations.new.mutation(root, { document: set }, context);
|
||||
return await collection.options.mutations.create.mutation(root, { document: set }, context);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// mutation for removing a specific document (same checks as edit mutation)
|
||||
|
||||
remove: {
|
||||
delete: {
|
||||
|
||||
name: `${collectionName}Remove`,
|
||||
name: options.legacy ? `${typeName}Remove` : `delete${Utils.capitalize(typeName)}`,
|
||||
|
||||
description: `Mutation for deleting a ${collectionName} document`,
|
||||
description: `Mutation for deleting a ${typeName} document`,
|
||||
|
||||
check(user, document) {
|
||||
if (options.removeCheck) {
|
||||
|
@ -134,17 +134,17 @@ export const getDefaultMutations = (collectionName, options = {}) => {
|
|||
}
|
||||
|
||||
if (!user || !document) return false;
|
||||
return Users.owns(user, document) ? Users.canDo(user, `${collectionName.toLowerCase()}.remove.own`) : Users.canDo(user, `${collectionName.toLowerCase()}.remove.all`);
|
||||
return Users.owns(user, document) ? Users.canDo(user, `${typeName.toLowerCase()}.remove.own`) : Users.canDo(user, `${typeName.toLowerCase()}.remove.all`);
|
||||
},
|
||||
|
||||
async mutation(root, {documentId}, context) {
|
||||
|
||||
const collection = context[collectionName];
|
||||
const collection = context[typeName];
|
||||
|
||||
const document = await Connectors.get(collection, documentId);
|
||||
Utils.performCheck(this.check, context.currentUser, document, context);
|
||||
|
||||
return await removeMutator({
|
||||
return await deleteMutator({
|
||||
collection,
|
||||
documentId: documentId,
|
||||
currentUser: context.currentUser,
|
||||
|
@ -164,28 +164,28 @@ const registerCollectionCallbacks = collectionName => {
|
|||
collectionName = collectionName.toLowerCase();
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.validate`,
|
||||
name: `${collectionName}.create.validate`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Validate a document before insertion (can be skipped when inserting directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.before`,
|
||||
name: `${collectionName}.create.before`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a new document before it's inserted in the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.after`,
|
||||
name: `${collectionName}.create.after`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a new document after it's inserted in the database but *before* the mutation returns it.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.async`,
|
||||
name: `${collectionName}.create.async`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
|
@ -193,28 +193,28 @@ const registerCollectionCallbacks = collectionName => {
|
|||
});
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.validate`,
|
||||
name: `${collectionName}.update.validate`,
|
||||
arguments: [{modifier: 'The MongoDB modifier'}, {document: 'The document being edited'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'modifier',
|
||||
description: `Validate a document before update (can be skipped when updating directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.before`,
|
||||
name: `${collectionName}.update.before`,
|
||||
arguments: [{modifier: 'The MongoDB modifier'}, {document: 'The document being edited'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'modifier',
|
||||
description: `Perform operations on a document before it's updated in the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.after`,
|
||||
name: `${collectionName}.update.after`,
|
||||
arguments: [{modifier: 'The MongoDB modifier'}, {document: 'The document being edited'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a document after it's updated in the database but *before* the mutation returns it.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.async`,
|
||||
name: `${collectionName}.update.async`,
|
||||
arguments: [{newDocument: 'The document after the edit'}, {document: 'The document before the edit'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
|
@ -222,21 +222,21 @@ const registerCollectionCallbacks = collectionName => {
|
|||
});
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.remove.validate`,
|
||||
name: `${collectionName}.delete.validate`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Validate a document before removal (can be skipped when removing directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.remove.before`,
|
||||
name: `${collectionName}.delete.before`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: null,
|
||||
description: `Perform operations on a document before it's removed from the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.remove.async`,
|
||||
name: `${collectionName}.delete.async`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
|
|
|
@ -9,20 +9,28 @@ import { createError } from 'apollo-errors';
|
|||
|
||||
const defaultOptions = {
|
||||
cacheMaxAge: 300,
|
||||
legacy: false,
|
||||
};
|
||||
|
||||
// note: for some reason changing resolverOptions to "options" throws error
|
||||
export const getDefaultResolvers = (collectionName, resolverOptions = defaultOptions) => {
|
||||
|
||||
// TODO: find more reliable way to get type name from collection name
|
||||
const typeName = collectionName.slice(0, -1);
|
||||
|
||||
return {
|
||||
// resolver for returning a list of documents based on a set of query terms
|
||||
|
||||
list: {
|
||||
name: `${collectionName}List`,
|
||||
|
||||
description: `A list of ${collectionName} documents matching a set of query terms`,
|
||||
name: resolverOptions.legacy ? `${typeName}List` : `${typeName}s`,
|
||||
|
||||
description: `A list of ${typeName} documents matching a set of query terms`,
|
||||
|
||||
async resolver(root, { terms = {}, enableCache = false }, context, { cacheControl }) {
|
||||
|
||||
debug('');
|
||||
debugGroup(`--------------- start \x1b[35m${collectionName} list\x1b[0m resolver ---------------`);
|
||||
debugGroup(`--------------- start \x1b[35m${typeName} list\x1b[0m resolver ---------------`);
|
||||
debug(`Options: ${JSON.stringify(resolverOptions)}`);
|
||||
debug(`Terms: ${JSON.stringify(terms)}`);
|
||||
|
||||
|
@ -58,7 +66,7 @@ export const getDefaultResolvers = (collectionName, resolverOptions = defaultOpt
|
|||
|
||||
debug(`\x1b[33m=> ${restrictedDocs.length} documents returned\x1b[0m`);
|
||||
debugGroupEnd();
|
||||
debug(`--------------- end \x1b[35m${collectionName} list\x1b[0m resolver ---------------`);
|
||||
debug(`--------------- end \x1b[35m${typeName} list\x1b[0m resolver ---------------`);
|
||||
debug('');
|
||||
|
||||
// return results
|
||||
|
@ -69,13 +77,13 @@ export const getDefaultResolvers = (collectionName, resolverOptions = defaultOpt
|
|||
// resolver for returning a single document queried based on id or slug
|
||||
|
||||
single: {
|
||||
name: `${collectionName}Single`,
|
||||
name: resolverOptions.legacy ? `${typeName}Single` : `${typeName}`,
|
||||
|
||||
description: `A single ${collectionName} document fetched by ID or slug`,
|
||||
description: `A single ${typeName} document fetched by ID or slug`,
|
||||
|
||||
async resolver(root, { documentId, slug, enableCache = false }, context, { cacheControl }) {
|
||||
debug('');
|
||||
debugGroup(`--------------- start \x1b[35m${collectionName} single\x1b[0m resolver ---------------`);
|
||||
debugGroup(`--------------- start \x1b[35m${typeName} single\x1b[0m resolver ---------------`);
|
||||
debug(`Options: ${JSON.stringify(resolverOptions)}`);
|
||||
debug(`DocumentId: ${documentId}, Slug: ${slug}`);
|
||||
|
||||
|
@ -106,7 +114,7 @@ export const getDefaultResolvers = (collectionName, resolverOptions = defaultOpt
|
|||
const restrictedDoc = Users.restrictViewableFields(currentUser, collection, doc);
|
||||
|
||||
debugGroupEnd();
|
||||
debug(`--------------- end \x1b[35m${collectionName} single\x1b[0m resolver ---------------`);
|
||||
debug(`--------------- end \x1b[35m${typeName} single\x1b[0m resolver ---------------`);
|
||||
debug('');
|
||||
|
||||
// filter out disallowed properties and return resulting document
|
||||
|
@ -117,9 +125,9 @@ export const getDefaultResolvers = (collectionName, resolverOptions = defaultOpt
|
|||
// resolver for returning the total number of documents matching a set of query terms
|
||||
|
||||
total: {
|
||||
name: `${collectionName}Total`,
|
||||
name: resolverOptions.legacy ? `${typeName}Total` : `total${typeName}s`,
|
||||
|
||||
description: `The total count of ${collectionName} documents matching a set of query terms`,
|
||||
description: `The total count of ${typeName} documents matching a set of query terms`,
|
||||
|
||||
async resolver(root, { terms, enableCache }, context, { cacheControl }) {
|
||||
if (cacheControl && enableCache) {
|
||||
|
|
|
@ -28,9 +28,15 @@ export { default as withAccess } from "./containers/withAccess.js";
|
|||
export { default as withMessages } from "./containers/withMessages.js";
|
||||
export { default as withList } from './containers/withList.js';
|
||||
export { default as withDocument } from './containers/withDocument.js';
|
||||
export { default as withNew } from './containers/withNew.js';
|
||||
export { default as withEdit } from './containers/withEdit.js';
|
||||
export { default as withRemove } from './containers/withRemove.js';
|
||||
export { default as withCreate } from './containers/withCreate.js';
|
||||
export { default as withUpdate } from './containers/withUpdate.js';
|
||||
export { default as withDelete } from './containers/withDelete.js';
|
||||
export { default as withCurrentUser } from './containers/withCurrentUser.js';
|
||||
export { default as withMutation } from './containers/withMutation.js';
|
||||
export { default as withUpsert } from './containers/withUpsert.js';
|
||||
|
||||
|
||||
// OpenCRUD backwards compatibility
|
||||
export { default as withNew } from './containers/withCreate.js';
|
||||
export { default as withEdit } from './containers/withUpdate.js';
|
||||
export { default as withRemove } from './containers/withDelete.js';
|
||||
|
|
|
@ -59,7 +59,7 @@ class EmbedURL extends Component {
|
|||
const result = await this.props.getEmbedData({ url });
|
||||
|
||||
// uncomment for debug
|
||||
console.log('Embedly Data', result);
|
||||
// console.log('Embedly Data', result);
|
||||
|
||||
// extract the relevant data, for easier consumption
|
||||
const { data: { getEmbedData: { title, description, thumbnailUrl } } } = result;
|
||||
|
|
|
@ -6,7 +6,6 @@ import { runCallbacks } from './callbacks.js';
|
|||
import { getSetting, registerSetting } from './settings.js';
|
||||
import { registerFragment, getDefaultFragmentText } from './fragments.js';
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import { isIntlField } from './intl.js';
|
||||
const wrapAsync = (Meteor.wrapAsync)? Meteor.wrapAsync : Meteor._wrapAsync;
|
||||
// import { debug } from './debug.js';
|
||||
|
||||
|
@ -166,7 +165,7 @@ export const createCollection = options => {
|
|||
if (resolvers) {
|
||||
const queryResolvers = {};
|
||||
// list
|
||||
if (resolvers.list) { // e.g. ""
|
||||
if (resolvers.list) {
|
||||
addGraphQLQuery(
|
||||
`${resolvers.list.name}(
|
||||
# A JSON object that contains the query terms used to fetch data
|
||||
|
@ -211,30 +210,30 @@ export const createCollection = options => {
|
|||
|
||||
if (mutations) {
|
||||
const mutationResolvers = {};
|
||||
// new
|
||||
if (mutations.new) { // e.g. "moviesNew(document: moviesInput) : Movie"
|
||||
// create
|
||||
if (mutations.create) { // e.g. "createMovie(document: moviesInput) : Movie"
|
||||
addGraphQLMutation(
|
||||
`${mutations.new.name}(
|
||||
# The document to insert
|
||||
`${mutations.create.name}(
|
||||
# The document to create
|
||||
document: ${collectionName}Input
|
||||
) : ${typeName}`, mutations.new.description);
|
||||
mutationResolvers[mutations.new.name] = mutations.new.mutation.bind(mutations.new);
|
||||
) : ${typeName}`, mutations.create.description);
|
||||
mutationResolvers[mutations.create.name] = mutations.create.mutation.bind(mutations.create);
|
||||
}
|
||||
// edit
|
||||
if (mutations.edit) { // e.g. "moviesEdit(documentId: String, set: moviesInput, unset: moviesUnset) : Movie"
|
||||
// update
|
||||
if (mutations.update) { // e.g. "updateMovie(documentId: String, set: moviesInput, unset: moviesUnset) : Movie"
|
||||
addGraphQLMutation(
|
||||
`${mutations.edit.name}(
|
||||
# The unique ID of the document to edit
|
||||
`${mutations.update.name}(
|
||||
# The unique ID of the document to update
|
||||
documentId: String,
|
||||
# An array of fields to insert
|
||||
set: ${collectionName}Input,
|
||||
# An array of fields to delete
|
||||
unset: ${collectionName}Unset
|
||||
) : ${typeName}`, mutations.edit.description);
|
||||
mutationResolvers[mutations.edit.name] = mutations.edit.mutation.bind(mutations.edit);
|
||||
) : ${typeName}`, mutations.update.description);
|
||||
mutationResolvers[mutations.update.name] = mutations.update.mutation.bind(mutations.update);
|
||||
}
|
||||
// upsert
|
||||
if (mutations.upsert) { // e.g. "moviesUpsert(search: moviesInput, set: moviesInput, unset: moviesUnset) : Movie"
|
||||
if (mutations.upsert) { // e.g. "upsertMovie(search: moviesInput, set: moviesInput, unset: moviesUnset) : Movie"
|
||||
addGraphQLMutation(
|
||||
`${mutations.upsert.name}(
|
||||
# The document to search for (or partial document)
|
||||
|
@ -246,14 +245,14 @@ export const createCollection = options => {
|
|||
) : ${typeName}`, mutations.upsert.description);
|
||||
mutationResolvers[mutations.upsert.name] = mutations.upsert.mutation.bind(mutations.upsert);
|
||||
}
|
||||
// remove
|
||||
if (mutations.remove) { // e.g. "moviesRemove(documentId: String) : Movie"
|
||||
// delete
|
||||
if (mutations.delete) { // e.g. "deleteMovie(documentId: String) : Movie"
|
||||
addGraphQLMutation(
|
||||
`${mutations.remove.name}(
|
||||
`${mutations.delete.name}(
|
||||
# The unique ID of the document to delete
|
||||
documentId: String
|
||||
) : ${typeName}`, mutations.remove.description);
|
||||
mutationResolvers[mutations.remove.name] = mutations.remove.mutation.bind(mutations.remove);
|
||||
) : ${typeName}`, mutations.delete.description);
|
||||
mutationResolvers[mutations.delete.name] = mutations.delete.mutation.bind(mutations.delete);
|
||||
}
|
||||
addGraphQLResolvers({ Mutation: { ...mutationResolvers } });
|
||||
}
|
||||
|
|
|
@ -36,10 +36,10 @@ import { Connectors } from './connectors.js';
|
|||
|
||||
registerSetting('database', 'mongo', 'Which database to use for your back-end');
|
||||
|
||||
export const newMutation = async ({ collection, document, currentUser, validate, context }) => {
|
||||
export const createMutator = async ({ collection, document, currentUser, validate, context }) => {
|
||||
|
||||
debug('//------------------------------------//');
|
||||
debug('// newMutation');
|
||||
debug('// createMutator');
|
||||
debug(collection._name);
|
||||
debug(`validate: ${validate}`);
|
||||
debug(document);
|
||||
|
@ -55,8 +55,10 @@ export const newMutation = async ({ collection, document, currentUser, validate,
|
|||
const validationErrors = validateDocument(newDocument, collection, context);
|
||||
|
||||
// run validation callbacks
|
||||
newDocument = runCallbacks(`${collectionName}.create.validate`, newDocument, currentUser, validationErrors);
|
||||
// OpenCRUD backwards compatibility
|
||||
newDocument = runCallbacks(`${collectionName}.new.validate`, newDocument, currentUser, validationErrors);
|
||||
|
||||
|
||||
if (validationErrors.length) {
|
||||
const NewDocumentValidationError = createError('app.validation_error', {message: 'app.new_document_validation_error'});
|
||||
throw new NewDocumentValidationError({data: {break: true, errors: validationErrors}});
|
||||
|
@ -89,6 +91,9 @@ export const newMutation = async ({ collection, document, currentUser, validate,
|
|||
// }
|
||||
|
||||
// run sync callbacks
|
||||
newDocument = await runCallbacks(`${collectionName}.create.before`, newDocument, currentUser);
|
||||
newDocument = await runCallbacks(`${collectionName}.create.sync`, newDocument, currentUser);
|
||||
// OpenCRUD backwards compatibility
|
||||
newDocument = await runCallbacks(`${collectionName}.new.before`, newDocument, currentUser);
|
||||
newDocument = await runCallbacks(`${collectionName}.new.sync`, newDocument, currentUser);
|
||||
|
||||
|
@ -96,6 +101,8 @@ export const newMutation = async ({ collection, document, currentUser, validate,
|
|||
newDocument._id = await Connectors.create(collection, newDocument);
|
||||
|
||||
// run any post-operation sync callbacks
|
||||
newDocument = await runCallbacks(`${collectionName}.create.after`, newDocument, currentUser);
|
||||
// OpenCRUD backwards compatibility
|
||||
newDocument = await runCallbacks(`${collectionName}.new.after`, newDocument, currentUser);
|
||||
|
||||
// get fresh copy of document from db
|
||||
|
@ -104,9 +111,11 @@ export const newMutation = async ({ collection, document, currentUser, validate,
|
|||
|
||||
// run async callbacks
|
||||
// note: query for document to get fresh document with collection-hooks effects applied
|
||||
await runCallbacksAsync(`${collectionName}.create.async`, insertedDocument, currentUser, collection);
|
||||
// OpenCRUD backwards compatibility
|
||||
await runCallbacksAsync(`${collectionName}.new.async`, insertedDocument, currentUser, collection);
|
||||
|
||||
debug('// new mutation finished:');
|
||||
debug('// createMutator finished:');
|
||||
debug(newDocument);
|
||||
debug('//------------------------------------//');
|
||||
|
||||
|
@ -114,7 +123,7 @@ export const newMutation = async ({ collection, document, currentUser, validate,
|
|||
}
|
||||
|
||||
|
||||
export const editMutation = async ({ collection, documentId, set = {}, unset = {}, currentUser, validate, context }) => {
|
||||
export const updateMutator = async ({ collection, documentId, set = {}, unset = {}, currentUser, validate, context }) => {
|
||||
|
||||
const collectionName = collection._name;
|
||||
const schema = collection.simpleSchema()._schema;
|
||||
|
@ -127,7 +136,7 @@ export const editMutation = async ({ collection, documentId, set = {}, unset = {
|
|||
let document = await Connectors.get(collection, documentId);
|
||||
|
||||
debug('//------------------------------------//');
|
||||
debug('// editMutation');
|
||||
debug('// updateMutator');
|
||||
debug('// collectionName: ', collection._name);
|
||||
debug('// documentId: ', documentId);
|
||||
debug('// set: ', set);
|
||||
|
@ -138,6 +147,8 @@ export const editMutation = async ({ collection, documentId, set = {}, unset = {
|
|||
|
||||
const validationErrors = validateModifier(modifier, document, collection, context);
|
||||
|
||||
modifier = runCallbacks(`${collectionName}.update.validate`, modifier, document, currentUser, validationErrors);
|
||||
// OpenCRUD backwards compatibility
|
||||
modifier = runCallbacks(`${collectionName}.edit.validate`, modifier, document, currentUser, validationErrors);
|
||||
|
||||
if (validationErrors.length) {
|
||||
|
@ -178,6 +189,9 @@ export const editMutation = async ({ collection, documentId, set = {}, unset = {
|
|||
// run sync callbacks (on mongo modifier)
|
||||
modifier = await runCallbacks(`${collectionName}.edit.before`, modifier, document, currentUser, newDocument);
|
||||
modifier = await runCallbacks(`${collectionName}.edit.sync`, modifier, document, currentUser, newDocument);
|
||||
// OpenCRUD backwards compatibility
|
||||
modifier = await runCallbacks(`${collectionName}.update.before`, modifier, document, currentUser, newDocument);
|
||||
modifier = await runCallbacks(`${collectionName}.update.sync`, modifier, document, currentUser, newDocument);
|
||||
|
||||
// remove empty modifiers
|
||||
if (_.isEmpty(modifier.$set)) {
|
||||
|
@ -201,23 +215,27 @@ export const editMutation = async ({ collection, documentId, set = {}, unset = {
|
|||
}
|
||||
|
||||
// run any post-operation sync callbacks
|
||||
newDocument = await runCallbacks(`${collectionName}.update.after`, newDocument, document, currentUser);
|
||||
// OpenCRUD backwards compatibility
|
||||
newDocument = await runCallbacks(`${collectionName}.edit.after`, newDocument, document, currentUser);
|
||||
|
||||
// run async callbacks
|
||||
await runCallbacksAsync(`${collectionName}.update.async`, newDocument, document, currentUser, collection);
|
||||
// OpenCRUD backwards compatibility
|
||||
await runCallbacksAsync(`${collectionName}.edit.async`, newDocument, document, currentUser, collection);
|
||||
|
||||
debug('// edit mutation finished')
|
||||
debug('// updateMutator finished')
|
||||
debug('// modifier: ', modifier)
|
||||
debug('// edited document: ', newDocument)
|
||||
debug('// updated document: ', newDocument)
|
||||
debug('//------------------------------------//');
|
||||
|
||||
return newDocument;
|
||||
}
|
||||
|
||||
export const removeMutation = async ({ collection, documentId, currentUser, validate, context }) => {
|
||||
export const deleteMutator = async ({ collection, documentId, currentUser, validate, context }) => {
|
||||
|
||||
debug('//------------------------------------//');
|
||||
debug('// removeMutation')
|
||||
debug('// deleteMutator')
|
||||
debug(collection._name)
|
||||
debug(documentId)
|
||||
debug('//------------------------------------//');
|
||||
|
@ -229,6 +247,8 @@ export const removeMutation = async ({ collection, documentId, currentUser, vali
|
|||
|
||||
// if document is not trusted, run validation callbacks
|
||||
if (validate) {
|
||||
document = runCallbacks(`${collectionName}.delete.validate`, document, currentUser);
|
||||
// OpenCRUD backwards compatibility
|
||||
document = runCallbacks(`${collectionName}.remove.validate`, document, currentUser);
|
||||
}
|
||||
|
||||
|
@ -239,6 +259,9 @@ export const removeMutation = async ({ collection, documentId, currentUser, vali
|
|||
}
|
||||
}
|
||||
|
||||
await runCallbacks(`${collectionName}.delete.before`, document, currentUser);
|
||||
await runCallbacks(`${collectionName}.delete.sync`, document, currentUser);
|
||||
// OpenCRUD backwards compatibility
|
||||
await runCallbacks(`${collectionName}.remove.before`, document, currentUser);
|
||||
await runCallbacks(`${collectionName}.remove.sync`, document, currentUser);
|
||||
|
||||
|
@ -249,11 +272,17 @@ export const removeMutation = async ({ collection, documentId, currentUser, vali
|
|||
collection.loader.clear(documentId);
|
||||
}
|
||||
|
||||
await runCallbacksAsync(`${collectionName}.delete.async`, document, currentUser, collection);
|
||||
// OpenCRUD backwards compatibility
|
||||
await runCallbacksAsync(`${collectionName}.remove.async`, document, currentUser, collection);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
export const newMutator = newMutation;
|
||||
export const editMutator = editMutation;
|
||||
export const removeMutator = removeMutation;
|
||||
// OpenCRUD backwards compatibility
|
||||
export const newMutation = createMutator;
|
||||
export const editMutation = updateMutator;
|
||||
export const removeMutation = deleteMutator;
|
||||
export const newMutator = createMutator;
|
||||
export const editMutator = updateMutator;
|
||||
export const removeMutator = deleteMutator;
|
|
@ -1,4 +1,4 @@
|
|||
import { newMutation, editMutation, removeMutation, Utils, Connectors } from 'meteor/vulcan:lib';
|
||||
import { createMutator, updateMutator, deleteMutator, Utils, Connectors } from 'meteor/vulcan:lib';
|
||||
import Users from './collection'; // TODO: circular dependency?
|
||||
|
||||
const performCheck = (mutation, user, document) => {
|
||||
|
@ -7,9 +7,9 @@ const performCheck = (mutation, user, document) => {
|
|||
|
||||
const mutations = {
|
||||
|
||||
new: {
|
||||
create: {
|
||||
|
||||
name: 'usersNew',
|
||||
name: 'createUser',
|
||||
|
||||
check(user, document) {
|
||||
if (!user) return false;
|
||||
|
@ -20,7 +20,7 @@ const mutations = {
|
|||
|
||||
performCheck(this, context.currentUser, document);
|
||||
|
||||
return newMutation({
|
||||
return createMutator({
|
||||
collection: context.Users,
|
||||
document: document,
|
||||
currentUser: context.currentUser,
|
||||
|
@ -31,9 +31,9 @@ const mutations = {
|
|||
|
||||
},
|
||||
|
||||
edit: {
|
||||
update: {
|
||||
|
||||
name: 'usersEdit',
|
||||
name: 'updateUser',
|
||||
|
||||
check(user, document) {
|
||||
if (!user || !document) return false;
|
||||
|
@ -45,7 +45,7 @@ const mutations = {
|
|||
const document = await Connectors.get(context.Users, documentId);
|
||||
performCheck(this, context.currentUser, document);
|
||||
|
||||
return editMutation({
|
||||
return updateMutator({
|
||||
collection: context.Users,
|
||||
documentId: documentId,
|
||||
set: set,
|
||||
|
@ -58,9 +58,9 @@ const mutations = {
|
|||
|
||||
},
|
||||
|
||||
remove: {
|
||||
delete: {
|
||||
|
||||
name: 'usersRemove',
|
||||
name: 'deleteUser',
|
||||
|
||||
check(user, document) {
|
||||
if (!user || !document) return false;
|
||||
|
@ -72,7 +72,7 @@ const mutations = {
|
|||
const document = await Connectors.get(context.Users, documentId);
|
||||
performCheck(this, context.currentUser, document);
|
||||
|
||||
return removeMutation({
|
||||
return deleteMutator({
|
||||
collection: context.Users,
|
||||
documentId: documentId,
|
||||
currentUser: context.currentUser,
|
||||
|
|
Loading…
Add table
Reference in a new issue