Skip to content
This repository has been archived by the owner on Nov 21, 2020. It is now read-only.

Commit

Permalink
Merge branch 'release-0.6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
batamar committed Sep 25, 2017
2 parents ed68c50 + f629b96 commit c2edd0c
Show file tree
Hide file tree
Showing 62 changed files with 5,815 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"presets": [
[
"env",
{
"targets": {
"node": "current"
}
}
]
],
"plugins": ["transform-object-rest-spread"]
}
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
NODE_ENV=development
PORT=3400
MONGO_URL=mongodb://localhost:3001/meteor
TEST_MONGO_URL=mongodb://localhost/erxesApiTest
21 changes: 21 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": [
"eslint:recommended"
],
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
"experimentalObjectRestSpread": true
}
},
"rules": {
"max-len": ["error", 100],
"no-underscore-dangle": ["error", { "allow": ["_id"] }]
}
}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
static
.DS_Store
npm-debug.log*
.env
coverage
60 changes: 60 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "erxes-app-api",
"version": "0.6.0",
"description": "GraphQL API for erxes main project",
"homepage": "https://erxes.io",
"repository": "https://github.com/erxes/erxes-app-api",
"bugs": "https://github.com/erxes/erxes-app-api/issues",
"keywords": [
"node",
"express",
"graphql",
"apollo"
],
"license": "MIT",
"private": true,
"scripts": {
"start": "node dist",
"dev": "NODE_ENV=development nodemon src --exec babel-node",
"build": "babel src --out-dir dist --ignore __tests__,tests --copy-files",
"lint": "eslint src",
"format": "prettier --write --print-width 100 --single-quote --trailing-comma all 'src/**/*.js'",
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"prettier --write --print-width 100 --single-quote --trailing-comma all",
"git add"
]
},
"dependencies": {
"body-parser": "^1.17.1",
"cors": "^2.8.1",
"dotenv": "^4.0.0",
"express": "^4.15.2",
"graphql": "^0.10.1",
"graphql-server-core": "^0.8.2",
"graphql-server-express": "^0.8.2",
"graphql-server-module-graphiql": "^0.8.2",
"graphql-subscriptions": "^0.4.3",
"graphql-tools": "^1.0.0",
"meteor-random": "^0.0.3",
"moment": "^2.18.1",
"mongoose": "^4.9.2",
"passport": "^0.4.0",
"passport-anonymous": "^1.0.1",
"passport-http-bearer": "^1.0.1",
"subscriptions-transport-ws": "^0.7.3",
"underscore": "^1.8.3"
},
"devDependencies": {
"babel-cli": "^6.24.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-preset-env": "^1.6.0",
"eslint": "3.19.0",
"husky": "^0.13.4",
"lint-staged": "^3.6.0",
"nodemon": "^1.11.0",
"prettier": "^1.4.4"
}
}
21 changes: 21 additions & 0 deletions src/data/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const CONVERSATION_STATUSES = {
NEW: 'new',
OPEN: 'open',
CLOSED: 'closed',
ALL_LIST: ['new', 'open', 'closed'],
};

export const INTEGRATION_KIND_CHOICES = {
MESSENGER: 'messenger',
FORM: 'form',
TWITTER: 'twitter',
FACEBOOK: 'facebook',
ALL_LIST: ['messenger', 'form', 'twitter', 'facebook'],
};

export const TAG_TYPES = {
CONVERSATION: 'conversation',
CUSTOMER: 'customer',
ENGAGE_MESSAGE: 'engageMessage',
ALL_LIST: ['conversation', 'customer', 'engageMessage'],
};
8 changes: 8 additions & 0 deletions src/data/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { makeExecutableSchema } from 'graphql-tools';
import resolvers from './resolvers';
import { types, queries, mutations, subscriptions } from './schema';

export default makeExecutableSchema({
typeDefs: [types, queries, mutations, subscriptions],
resolvers,
});
37 changes: 37 additions & 0 deletions src/data/resolvers/conversation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ConversationMessages, Customers, Integrations, Users, Tags } from '../../db/models';

export default {
customer(conversation) {
return Customers.findOne({ _id: conversation.customerId });
},

integration(conversation) {
return Integrations.findOne({ _id: conversation.integrationId });
},

user(conversation) {
return Users.findOne({ _id: conversation.userId });
},

assignedUser(conversation) {
return Users.findOne({ _id: conversation.assignedUserId });
},

participatedUsers(conv) {
return Users.find({
_id: { $in: conv.participatedUserIds || [] },
});
},

participatorCount(conv) {
return (conv.participatedUserIds && conv.participatedUserIds.length) || 0;
},

messages(conv) {
return ConversationMessages.find({ conversationId: conv._id }).sort({ createdAt: 1 });
},

tags(conv) {
return Tags.find({ _id: { $in: conv.tagIds || [] } });
},
};
11 changes: 11 additions & 0 deletions src/data/resolvers/conversationMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Users, Customers } from '../../db/models';

export default {
user(message) {
return Users.findOne({ _id: message.userId });
},

customer(message) {
return Customers.findOne({ _id: message.customerId });
},
};
59 changes: 59 additions & 0 deletions src/data/resolvers/customScalars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { GraphQLScalarType } from 'graphql';
import { Kind } from 'graphql/language';

function jSONidentity(value) {
return value;
}

function jSONparseLiteral(ast) {
switch (ast.kind) {
case Kind.STRING:
case Kind.BOOLEAN:
return ast.value;
case Kind.INT:
case Kind.FLOAT:
return parseFloat(ast.value);
case Kind.OBJECT: {
const value = Object.create(null);
ast.fields.forEach(field => {
value[field.name.value] = jSONparseLiteral(field.value);
});

return value;
}
case Kind.LIST:
return ast.values.map(jSONparseLiteral);
default:
return null;
}
}

export default {
Date: new GraphQLScalarType({
name: 'Date',
description: 'Date custom scalar type',
parseValue(value) {
return new Date(value); // value from the client
},
serialize(value) {
return value.getTime(); // value sent to the client
},
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return parseInt(ast.value, 10); // ast value is always in string format
}
return null;
},
}),

JSON: new GraphQLScalarType({
name: 'JSON',
description:
'The `jSON` scalar type represents jSON values as specified by ' +
'[ECMA-404](http://www.ecma-international.org/' +
'publications/files/ECMA-ST/ECMA-404.pdf).',
serialize: jSONidentity,
parseValue: jSONidentity,
parseLiteral: jSONparseLiteral,
}),
};
34 changes: 34 additions & 0 deletions src/data/resolvers/customer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Conversations, Tags } from '../../db/models';

export default {
getIntegrationData(customer) {
return {
messenger: customer.messengerData || {},
twitter: customer.twitterData || {},
facebook: customer.facebookData || {},
};
},

getMessengerCustomData(customer) {
const results = [];
const messengerData = customer.messengerData || {};
const data = messengerData.customData || {};

Object.keys(data).forEach(key => {
results.push({
name: key.replace(/_/g, ' '),
value: data[key],
});
});

return results;
},

getTags(customer) {
return Tags.find({ _id: { $in: customer.tagIds || [] } });
},

conversations(customer) {
return Conversations.find({ customerId: customer._id });
},
};
11 changes: 11 additions & 0 deletions src/data/resolvers/engage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Segments, Users } from '../../db/models';

export default {
segment(engageMessage) {
return Segments.findOne({ _id: engageMessage.segmentId });
},

fromUser(engageMessage) {
return Users.findOne({ _id: engageMessage.fromUserId });
},
};
7 changes: 7 additions & 0 deletions src/data/resolvers/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FormFields } from '../../db/models';

export default {
fields(form) {
return FormFields.find({ formId: form._id }).sort({ order: 1 });
},
};
29 changes: 29 additions & 0 deletions src/data/resolvers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import customScalars from './customScalars';
import Mutation from './mutations';
import Query from './queries';
import Subscription from './subscriptions';
import ResponseTemplate from './responseTemplate';
import Integration from './integration';
import Form from './form';
import EngageMessage from './engage';
import Customer from './customer';
import Segment from './segment';
import Conversation from './conversation';
import ConversationMessage from './conversationMessage';

export default {
...customScalars,

ResponseTemplate,
Integration,
Form,
Customer,
Segment,
EngageMessage,
Conversation,
ConversationMessage,

Mutation,
Query,
Subscription,
};
15 changes: 15 additions & 0 deletions src/data/resolvers/integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Channels, Brands, Forms } from '../../db/models';

export default {
brand(integration) {
return Brands.findOne({ _id: integration.brandId });
},

form(integration) {
return Forms.findOne({ _id: integration.formId });
},

channels(integration) {
return Channels.find({ integrationIds: { $in: [integration._id] } });
},
};
39 changes: 39 additions & 0 deletions src/data/resolvers/mutations/conversation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Will implement actual db changes after removing meteor
*/

import { Conversations, ConversationMessages } from '../../../db/models';
import { pubsub } from '../subscriptions';

export default {
async conversationMessageInserted(root, { _id }) {
const message = await ConversationMessages.findOne({ _id });
const conversationId = message.conversationId;
const conversation = await Conversations.findOne({ _id: conversationId });

pubsub.publish('conversationMessageInserted', {
conversationMessageInserted: message,
});

pubsub.publish('conversationsChanged', {
conversationsChanged: { customerId: conversation.customerId, type: 'newMessage' },
});

return 'done';
},

async conversationsChanged(root, { _ids, type }) {
for (let _id of _ids) {
const conversation = await Conversations.findOne({ _id });

// notify new message
pubsub.publish('conversationChanged', {
conversationChanged: { conversationId: _id, type },
});

pubsub.publish('conversationsChanged', {
conversationsChanged: { customerId: conversation.customerId, type },
});
}
},
};
5 changes: 5 additions & 0 deletions src/data/resolvers/mutations/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import conversation from './conversation';

export default {
...conversation,
};
Loading

0 comments on commit c2edd0c

Please sign in to comment.