@zohoim/client-sdk 1.0.0-poc1 → 1.0.0-poc10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/es/config/urls/channels/channel-agents-api-url.js +11 -0
  2. package/es/config/urls/channels/index.js +2 -0
  3. package/es/config/urls/index.js +1 -0
  4. package/es/config/urls/sessions/sessions-api-url.js +12 -0
  5. package/es/core/constants/HttpMethods.js +8 -0
  6. package/es/core/constants/ModuleNames.js +5 -0
  7. package/es/core/constants/index.js +4 -0
  8. package/es/core/errors/AdapterError.js +7 -0
  9. package/es/core/errors/index.js +3 -0
  10. package/es/core/utils/index.js +2 -0
  11. package/es/core/utils/validateSchema.js +68 -0
  12. package/es/domain/entities/Actor/Actor.js +23 -0
  13. package/es/domain/entities/Actor/index.js +2 -2
  14. package/es/domain/entities/Agent/Agent.js +13 -102
  15. package/es/domain/entities/Agent/index.js +1 -1
  16. package/es/domain/entities/Session/Session.js +38 -0
  17. package/es/domain/entities/Session/index.js +2 -0
  18. package/es/domain/entities/index.js +2 -1
  19. package/es/domain/enum/actor/index.js +2 -0
  20. package/es/domain/enum/index.js +3 -0
  21. package/es/domain/enum/integrationServices/IntegrationServices.js +11 -0
  22. package/es/domain/enum/integrationServices/index.js +2 -0
  23. package/es/domain/enum/session/SessionReplyStatus.js +20 -0
  24. package/es/domain/enum/session/SessionStatus.js +9 -0
  25. package/es/domain/enum/session/index.js +3 -0
  26. package/es/domain/interfaces/BaseAPI.js +58 -0
  27. package/es/domain/interfaces/channels/IChannelAgent.js +15 -2
  28. package/es/domain/interfaces/index.js +2 -1
  29. package/es/domain/interfaces/sessions/ISession.js +19 -0
  30. package/es/domain/interfaces/sessions/index.js +2 -0
  31. package/es/domain/schema/actor/ActorSchema.js +33 -0
  32. package/es/domain/schema/actor/AgentSchema.js +29 -0
  33. package/es/domain/schema/actor/index.js +3 -0
  34. package/es/domain/schema/index.js +2 -0
  35. package/es/domain/schema/session/SessionSchema.js +86 -0
  36. package/es/domain/schema/session/index.js +2 -0
  37. package/es/domain/services/channels/ChannelAgentService.js +18 -5
  38. package/es/domain/services/sessions/SessionService.js +27 -0
  39. package/es/domain/services/sessions/index.js +2 -0
  40. package/es/index.js +8 -1
  41. package/es/infrastructure/adapters/BaseAdapter.js +23 -0
  42. package/es/infrastructure/adapters/channels/ChannelAgentAdapter.js +35 -0
  43. package/es/infrastructure/adapters/channels/index.js +2 -0
  44. package/es/infrastructure/adapters/index.js +2 -0
  45. package/es/infrastructure/adapters/sessions/SessionAdapter.js +37 -0
  46. package/es/infrastructure/adapters/sessions/index.js +2 -0
  47. package/es/infrastructure/api/channels/ChannelAgentAPI.js +26 -0
  48. package/es/infrastructure/api/channels/index.js +2 -0
  49. package/es/infrastructure/api/index.js +1 -0
  50. package/es/infrastructure/api/sessions/SessionAPI.js +25 -0
  51. package/es/infrastructure/api/sessions/index.js +2 -0
  52. package/es/infrastructure/interfaces/api/channels/agents/GetChannelAgentsRequest.js +13 -0
  53. package/es/infrastructure/interfaces/api/channels/agents/index.js +2 -0
  54. package/es/infrastructure/interfaces/api/channels/index.js +1 -0
  55. package/es/infrastructure/interfaces/api/index.js +2 -0
  56. package/es/infrastructure/interfaces/api/sessions/UpdateSessionAssigneeRequest.js +12 -0
  57. package/es/infrastructure/interfaces/api/sessions/index.js +2 -0
  58. package/es/infrastructure/interfaces/index.js +1 -0
  59. package/es/infrastructure/managers/ModuleFactory.js +26 -0
  60. package/es/infrastructure/managers/ModuleManager.js +46 -0
  61. package/es/infrastructure/managers/index.js +2 -0
  62. package/es/infrastructure/sdk/IMSDK.js +29 -0
  63. package/es/infrastructure/sdk/channels/ChannelAgentsSDK.js +22 -0
  64. package/es/infrastructure/sdk/channels/ChannelSDK.js +19 -0
  65. package/es/infrastructure/sdk/channels/index.js +2 -0
  66. package/es/infrastructure/sdk/index.js +2 -0
  67. package/es/infrastructure/sdk/sessions/SessionSDK.js +22 -0
  68. package/es/infrastructure/sdk/sessions/index.js +2 -0
  69. package/package.json +1 -7
  70. package/es/domain/index.js +0 -3
  71. /package/es/{domain → core}/errors/ValidationError.js +0 -0
  72. /package/es/domain/{entities/Actor → enum/actor}/ActorType.js +0 -0
@@ -0,0 +1,11 @@
1
+ import { HTTP_METHODS, IM_API_PREFIX } from '../../../core/constants';
2
+ import { GetChannelAgentsRequest } from '../../../infrastructure/interfaces/api';
3
+ const BASE_URL = `${IM_API_PREFIX}/channels/:channelId/agents`;
4
+ const CHANNEL_AGENTS_API_URLS = {
5
+ LIST: {
6
+ url: BASE_URL,
7
+ method: HTTP_METHODS.GET,
8
+ ...GetChannelAgentsRequest
9
+ }
10
+ };
11
+ export default CHANNEL_AGENTS_API_URLS;
@@ -0,0 +1,2 @@
1
+ import CHANNEL_AGENTS_API_URLS from './channel-agents-api-url';
2
+ export { CHANNEL_AGENTS_API_URLS };
@@ -0,0 +1 @@
1
+ export * from './channels';
@@ -0,0 +1,12 @@
1
+ import { UpdateSessionAssigneeRequest } from '../../../infrastructure/interfaces/api';
2
+ import { HTTP_METHODS, IM_API_PREFIX } from '../../../core/constants';
3
+ const BASE_URL = `${IM_API_PREFIX}/sessions`;
4
+ const SINGLE_SESSION_URL = `${BASE_URL}/:sessionId`;
5
+ const SESSIONS_API_URLS = {
6
+ UPDATE_SESSION_ASSIGNEE: {
7
+ url: SINGLE_SESSION_URL,
8
+ method: HTTP_METHODS.PATCH,
9
+ ...UpdateSessionAssigneeRequest
10
+ }
11
+ };
12
+ export default SESSIONS_API_URLS;
@@ -0,0 +1,8 @@
1
+ const HTTP_METHODS = {
2
+ GET: 'GET',
3
+ POST: 'POST',
4
+ PUT: 'PUT',
5
+ PATCH: 'PATCH',
6
+ DELETE: 'DELETE'
7
+ };
8
+ export default HTTP_METHODS;
@@ -0,0 +1,5 @@
1
+ const ModuleNames = {
2
+ CHANNELS: 'channels',
3
+ SESSIONS: 'sessions'
4
+ };
5
+ export default ModuleNames;
@@ -0,0 +1,4 @@
1
+ import HTTP_METHODS from './HTTPMethods';
2
+ import ModuleNames from './ModuleNames';
3
+ const IM_API_PREFIX = '/api/v1';
4
+ export { ModuleNames, IM_API_PREFIX, HTTP_METHODS };
@@ -0,0 +1,7 @@
1
+ export default class AdapterError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'AdapterError';
5
+ }
6
+
7
+ }
@@ -0,0 +1,3 @@
1
+ import AdapterError from './AdapterError';
2
+ import ValidationError from './ValidationError';
3
+ export { ValidationError, AdapterError };
@@ -0,0 +1,2 @@
1
+ import { validateSchema } from './validateSchema';
2
+ export { validateSchema };
@@ -0,0 +1,68 @@
1
+ import { ValidationError } from '../errors';
2
+
3
+ function validateSchemaKeys(schema, data) {
4
+ Object.keys(schema).forEach(key => {
5
+ if (!(key in data)) {
6
+ throw new ValidationError(`Key '${key}' is missing in the data`);
7
+ }
8
+ });
9
+ }
10
+
11
+ function validateRequiredCheck(_ref) {
12
+ let {
13
+ value,
14
+ rules,
15
+ path
16
+ } = _ref;
17
+
18
+ if (rules.required && !value) {
19
+ throw new ValidationError(rules.message || `${path} is required`);
20
+ }
21
+ }
22
+
23
+ function validateEnumCheck(_ref2) {
24
+ let {
25
+ value,
26
+ rules,
27
+ path
28
+ } = _ref2;
29
+
30
+ if (rules.enum && !rules.enum.includes(value)) {
31
+ throw new ValidationError(`${path} must be one of: ${rules.enum.join(', ')}`);
32
+ }
33
+ }
34
+
35
+ export const validateSchema = (schema, data) => {
36
+ const validate = function (schemaObj, dataObj) {
37
+ let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
38
+ // Check if all schema keys exist in data
39
+ validateSchemaKeys(schemaObj, dataObj); // Validate each field
40
+
41
+ Object.entries(schemaObj).forEach(_ref3 => {
42
+ let [field, rules] = _ref3;
43
+ const value = dataObj[field];
44
+ const fieldPath = path ? `${path}.${field}` : field;
45
+ validateRequiredCheck({
46
+ value,
47
+ rules,
48
+ path: fieldPath
49
+ });
50
+
51
+ if (value !== null && value !== undefined) {
52
+ // Enum validation
53
+ validateEnumCheck({
54
+ value,
55
+ rules,
56
+ path: fieldPath
57
+ }); // Nested object validation
58
+
59
+ if (rules.type === 'object' && rules.schema) {
60
+ validate(rules.schema, value, fieldPath);
61
+ }
62
+ }
63
+ });
64
+ return dataObj;
65
+ };
66
+
67
+ return validate(schema, data);
68
+ };
@@ -0,0 +1,23 @@
1
+ import { validateSchema } from '../../../core/utils';
2
+ import { ActorSchema } from '../../schema';
3
+ export default class Actor {
4
+ constructor() {
5
+ let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6
+ const validatedData = validateSchema(ActorSchema, data);
7
+ this.data = {
8
+ name: validatedData.name,
9
+ type: validatedData.type,
10
+ photoURL: validatedData.photoURL,
11
+ extId: validatedData.extId,
12
+ id: validatedData.id,
13
+ email: validatedData.email,
14
+ botType: validatedData.botType
15
+ };
16
+ }
17
+
18
+ toJSON() {
19
+ return { ...this.data
20
+ };
21
+ }
22
+
23
+ }
@@ -1,2 +1,2 @@
1
- import ActorType from './ActorType';
2
- export { ActorType };
1
+ import Actor from './Actor';
2
+ export { Actor };
@@ -1,110 +1,21 @@
1
- import ValidationError from '../../errors/ValidationError';
2
- import ActorType from '../Actor/ActorType';
1
+ import { validateSchema } from '../../../core/utils';
2
+ import { AgentSchema } from '../../schema';
3
3
  export default class Agent {
4
4
  constructor() {
5
- let {
6
- id = '',
7
- name = '',
8
- email = '',
9
- photoURL = '',
10
- zuid = '',
11
- type = ''
12
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13
- this.validateFields({
14
- id,
15
- email,
16
- name,
17
- zuid
18
- });
19
- this._id = id;
20
- this._name = name;
21
- this._email = email;
22
- this._photoURL = photoURL;
23
- this._zuid = zuid;
24
- this.setType(type);
25
- }
26
-
27
- validateFields(_ref) {
28
- let {
29
- id,
30
- email,
31
- name,
32
- zuid
33
- } = _ref;
34
- this.validateId(id);
35
- this.validateEmail(email);
36
- this.validateName(name);
37
- this.validateZuid(zuid);
38
- }
39
-
40
- static validateId(id) {
41
- if (!id) {
42
- throw new ValidationError('Agent ID is required');
43
- }
44
- }
45
-
46
- static validateEmail(email) {
47
- if (!email) {
48
- throw new ValidationError('Agent email is required');
49
- }
50
- }
51
-
52
- static validateName(name) {
53
- if (!name) {
54
- throw new ValidationError('Agent name is required');
55
- }
56
- }
57
-
58
- static validateZuid(zuid) {
59
- if (!zuid) {
60
- throw new ValidationError('Agent zuid is required');
61
- }
62
- }
63
-
64
- static validateType(type) {
65
- return type === ActorType.AGENT;
66
- }
67
-
68
- setType(type) {
69
- if (!Agent.validateType(type)) {
70
- throw new Error('Invalid actor type. Must be AGENT');
71
- }
72
-
73
- this._type = type;
74
- }
75
-
76
- get id() {
77
- return this._id;
78
- }
79
-
80
- get name() {
81
- return this._name;
82
- }
83
-
84
- get email() {
85
- return this._email;
86
- }
87
-
88
- get photoURL() {
89
- return this._photoURL;
90
- }
91
-
92
- get zuid() {
93
- return this._zuid;
94
- }
95
-
96
- get type() {
97
- return this._type;
5
+ let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6
+ const validatedData = validateSchema(AgentSchema, data);
7
+ this.data = {
8
+ id: validatedData.id,
9
+ name: validatedData.name,
10
+ email: validatedData.email,
11
+ photoURL: validatedData.photoURL || '',
12
+ zuid: validatedData.zuid,
13
+ type: validatedData.type
14
+ };
98
15
  }
99
16
 
100
17
  toJSON() {
101
- return {
102
- id: this._id,
103
- name: this._name,
104
- email: this._email,
105
- photoURL: this._photoURL,
106
- zuid: this._zuid,
107
- type: this._type
18
+ return { ...this.data
108
19
  };
109
20
  }
110
21
 
@@ -1,2 +1,2 @@
1
1
  import Agent from './Agent';
2
- export { Agent }; //
2
+ export { Agent };
@@ -0,0 +1,38 @@
1
+ import { validateSchema } from '../../../core/utils';
2
+ import { SessionSchema } from '../../schema';
3
+ import { Actor } from '../Actor';
4
+ export default class Session {
5
+ constructor() {
6
+ let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
7
+ const validatedData = validateSchema(SessionSchema, data);
8
+ this.data = {
9
+ channelId: validatedData.channelId,
10
+ status: validatedData.status,
11
+ createdTime: validatedData.createdTime,
12
+ agentId: validatedData.agentId,
13
+ botId: validatedData.botId,
14
+ actor: new Actor(validatedData.actor),
15
+ subject: validatedData.subject,
16
+ messagesCount: validatedData.messagesCount,
17
+ agentLastActiveTime: validatedData.agentLastActiveTime,
18
+ contactLastActiveTime: validatedData.contactLastActiveTime,
19
+ lastActiveTime: validatedData.lastActiveTime,
20
+ unreadMessagesCount: validatedData.unreadMessagesCount,
21
+ integrationServiceId: validatedData.integrationServiceId,
22
+ replyStatus: validatedData.replyStatus,
23
+ id: validatedData.id,
24
+ contactId: validatedData.contactId,
25
+ meta: validatedData.meta,
26
+ assignee: validatedData.assignee ? new Actor(validatedData.assignee) : null,
27
+ channel: validatedData.channel
28
+ };
29
+ }
30
+
31
+ toJSON() {
32
+ return { ...this.data,
33
+ actor: this.data.actor.toJSON(),
34
+ assignee: this.data.assignee?.toJSON()
35
+ };
36
+ }
37
+
38
+ }
@@ -0,0 +1,2 @@
1
+ import Session from './Session';
2
+ export { Session };
@@ -1,2 +1,3 @@
1
1
  export * from './Actor';
2
- export * from './Agent';
2
+ export * from './Agent';
3
+ export * from './Session';
@@ -0,0 +1,2 @@
1
+ import ActorType from './ActorType';
2
+ export { ActorType };
@@ -0,0 +1,3 @@
1
+ export * from './integrationServices';
2
+ export * from './session';
3
+ export * from './actor';
@@ -0,0 +1,11 @@
1
+ const IntegrationServices = {
2
+ TWILIO: 'TWILIO',
3
+ WHATSAPP: 'WHATSAPP',
4
+ TELEGRAM: 'TELEGRAM',
5
+ WECHAT: 'WECHAT',
6
+ LINE: 'LINE',
7
+ IM_TALK: 'IM_TALK',
8
+ FACEBOOKMESSENGER: 'FACEBOOKMESSENGER',
9
+ INSTAGRAM: 'INSTAGRAM'
10
+ };
11
+ export default IntegrationServices;
@@ -0,0 +1,2 @@
1
+ import IntegrationServices from './IntegrationServices';
2
+ export { IntegrationServices };
@@ -0,0 +1,20 @@
1
+ const SessionReplyStatus = {
2
+ ACCEPTED: 'ACCEPTED',
3
+ CHANNEL_INACTIVE: 'CHANNEL_INACTIVE',
4
+ CHANNEL_REVOKED: 'CHANNEL_REVOKED',
5
+ SESSION_ENDED: 'SESSION_ENDED',
6
+ SESSION_BLOCKED: 'SESSION_BLOCKED',
7
+ SESSION_EXPIRED: 'SESSION_EXPIRED',
8
+ UNASSIGNED: 'UNASSIGNED',
9
+ NOT_AN_ASSIGNEE: 'NOT_AN_ASSIGNEE',
10
+ CREDIT_EXHAUSTED: 'CREDIT_EXHAUSTED',
11
+ ACCESSTOKEN_EXPIRED: 'ACCESSTOKEN_EXPIRED',
12
+ PERMISSION_REVOKED: 'PERMISSION_REVOKED',
13
+ UNEXPECTED_ERROR: 'UNEXPECTED_ERROR',
14
+ PAGE_REMOVED: 'PAGE_REMOVED',
15
+ SANDBOX_LIMIT_REACHED: 'SANDBOX_LIMIT_REACHED',
16
+ CHANNEL_DELETED: 'CHANNEL_DELETED',
17
+ ENDUSER_OFFLINE: 'ENDUSER_OFFLINE',
18
+ CONFIG_SKIPPED_CHANNEL: 'CONFIG_SKIPPED_CHANNEL'
19
+ };
20
+ export default SessionReplyStatus;
@@ -0,0 +1,9 @@
1
+ const SessionStatus = {
2
+ CREATED: 'CREATED',
3
+ OPEN: 'OPEN',
4
+ ON_PROGRESS: 'ON_PROGRESS',
5
+ ON_HOLD: 'ON_HOLD',
6
+ ENDED: 'ENDED',
7
+ BLOCKED: 'BLOCKED'
8
+ };
9
+ export default SessionStatus;
@@ -0,0 +1,3 @@
1
+ import SessionReplyStatus from './SessionReplyStatus';
2
+ import SessionStatus from './SessionStatus';
3
+ export { SessionStatus, SessionReplyStatus };
@@ -0,0 +1,58 @@
1
+ export default class BaseAPI {
2
+ constructor(_ref) {
3
+ let {
4
+ httpClient
5
+ } = _ref;
6
+ this.httpClient = httpClient;
7
+ }
8
+
9
+ replacePathParams(url, params) {
10
+ let _url = url;
11
+ Object.entries(params).forEach(_ref2 => {
12
+ let [key, value] = _ref2;
13
+ _url = url.replace(`:${key}`, value);
14
+ });
15
+ return _url;
16
+ }
17
+
18
+ buildUrl(_ref3) {
19
+ let {
20
+ url,
21
+ params,
22
+ query
23
+ } = _ref3;
24
+
25
+ const _url = this.replacePathParams(url, params);
26
+
27
+ const queryString = this.buildQuery(query);
28
+
29
+ if (queryString) {
30
+ return `${_url}?${queryString}`;
31
+ }
32
+
33
+ return _url;
34
+ }
35
+
36
+ buildQuery(object) {
37
+ return new URLSearchParams(object).toString();
38
+ }
39
+
40
+ async request(_ref4) {
41
+ let {
42
+ urlConfig,
43
+ request
44
+ } = _ref4;
45
+ const url = this.buildUrl({
46
+ url: urlConfig.url,
47
+ params: request.params,
48
+ query: request.query
49
+ });
50
+ const httpRequest = await this.httpClient.request({
51
+ url,
52
+ method: urlConfig.method,
53
+ header: urlConfig.header
54
+ });
55
+ return httpRequest;
56
+ }
57
+
58
+ }
@@ -1,5 +1,18 @@
1
- export default class IChannelAgent {
2
- static getChannelAgents() {
1
+ import { GetChannelAgentsRequest } from '../../../infrastructure/interfaces/api';
2
+ import BaseAPI from '../BaseAPI';
3
+ export default class IChannelAgent extends BaseAPI {
4
+ constructor(_ref) {
5
+ let {
6
+ httpClient
7
+ } = _ref;
8
+ super({
9
+ httpClient
10
+ });
11
+ } // eslint-disable-next-line no-unused-vars
12
+
13
+
14
+ getChannelAgents() {
15
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GetChannelAgentsRequest;
3
16
  throw new Error('Method not implemented.');
4
17
  }
5
18
 
@@ -1 +1,2 @@
1
- export * from './channels';
1
+ export * from './channels';
2
+ export * from './sessions';
@@ -0,0 +1,19 @@
1
+ import { UpdateSessionAssigneeRequest } from '../../../infrastructure/interfaces/api';
2
+ import BaseAPI from '../BaseAPI';
3
+ export default class ISession extends BaseAPI {
4
+ constructor(_ref) {
5
+ let {
6
+ httpClient
7
+ } = _ref;
8
+ super({
9
+ httpClient
10
+ });
11
+ } // eslint-disable-next-line no-unused-vars
12
+
13
+
14
+ updateAssignee() {
15
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : UpdateSessionAssigneeRequest;
16
+ throw new Error('Method not implemented.');
17
+ }
18
+
19
+ }
@@ -0,0 +1,2 @@
1
+ import ISession from './ISession';
2
+ export { ISession };
@@ -0,0 +1,33 @@
1
+ import { ActorType } from '../../enum';
2
+ const ActorSchema = {
3
+ name: {
4
+ type: 'string',
5
+ required: true
6
+ },
7
+ type: {
8
+ type: 'string',
9
+ required: true,
10
+ enum: Object.values(ActorType)
11
+ },
12
+ photoURL: {
13
+ type: 'string',
14
+ required: false
15
+ },
16
+ extId: {
17
+ type: 'string',
18
+ required: false
19
+ },
20
+ id: {
21
+ type: 'string',
22
+ required: true
23
+ },
24
+ email: {
25
+ type: 'string',
26
+ required: false
27
+ },
28
+ botType: {
29
+ type: 'string',
30
+ required: false
31
+ }
32
+ };
33
+ export default ActorSchema;
@@ -0,0 +1,29 @@
1
+ import { ActorType } from '../../enum';
2
+ const AgentSchema = {
3
+ id: {
4
+ type: 'string',
5
+ required: true
6
+ },
7
+ name: {
8
+ type: 'string',
9
+ required: true
10
+ },
11
+ email: {
12
+ type: 'string',
13
+ required: true
14
+ },
15
+ photoURL: {
16
+ type: 'string',
17
+ required: false
18
+ },
19
+ zuid: {
20
+ type: 'string',
21
+ required: true
22
+ },
23
+ type: {
24
+ type: 'string',
25
+ required: true,
26
+ enum: [ActorType.AGENT]
27
+ }
28
+ };
29
+ export default AgentSchema;
@@ -0,0 +1,3 @@
1
+ import ActorSchema from './ActorSchema';
2
+ import AgentSchema from './AgentSchema';
3
+ export { ActorSchema, AgentSchema };
@@ -0,0 +1,2 @@
1
+ export * from './actor';
2
+ export * from './session';
@@ -0,0 +1,86 @@
1
+ import { IntegrationServices, SessionReplyStatus, SessionStatus } from '../../enum';
2
+ import { ActorSchema } from '../actor';
3
+ const SessionSchema = {
4
+ channelId: {
5
+ type: 'string',
6
+ required: true
7
+ },
8
+ status: {
9
+ type: 'string',
10
+ required: true,
11
+ enum: Object.values(SessionStatus)
12
+ },
13
+ createdTime: {
14
+ type: 'string',
15
+ required: true
16
+ },
17
+ agentId: {
18
+ type: 'string',
19
+ required: false
20
+ },
21
+ botId: {
22
+ type: 'string',
23
+ required: false
24
+ },
25
+ actor: {
26
+ type: 'object',
27
+ required: true,
28
+ schema: ActorSchema
29
+ },
30
+ subject: {
31
+ type: 'string',
32
+ required: true
33
+ },
34
+ messagesCount: {
35
+ type: 'string',
36
+ required: true
37
+ },
38
+ agentLastActiveTime: {
39
+ type: 'string',
40
+ required: true
41
+ },
42
+ contactLastActiveTime: {
43
+ type: 'string',
44
+ required: true
45
+ },
46
+ lastActiveTime: {
47
+ type: 'string',
48
+ required: true
49
+ },
50
+ unreadMessagesCount: {
51
+ type: 'string',
52
+ required: true
53
+ },
54
+ integrationServiceId: {
55
+ type: 'string',
56
+ required: true,
57
+ enum: Object.values(IntegrationServices)
58
+ },
59
+ replyStatus: {
60
+ type: 'string',
61
+ required: true,
62
+ enum: Object.values(SessionReplyStatus)
63
+ },
64
+ id: {
65
+ type: 'string',
66
+ required: true
67
+ },
68
+ contactId: {
69
+ type: 'string',
70
+ required: true
71
+ },
72
+ meta: {
73
+ type: 'array',
74
+ required: false
75
+ },
76
+ assignee: {
77
+ type: 'object',
78
+ required: false,
79
+ schema: ActorSchema
80
+ },
81
+ channel: {
82
+ type: 'string',
83
+ required: true
84
+ }
85
+ };
86
+ export default SessionSchema;
@@ -0,0 +1,2 @@
1
+ import SessionSchema from './SessionSchema';
2
+ export { SessionSchema };
@@ -1,13 +1,26 @@
1
- import IChannelAgent from '../../interfaces/channels/IChannelAgent';
1
+ import { CHANNEL_AGENTS_API_URLS } from '../../../config/urls/channels';
2
+ import { ChannelAgentAdapter } from '../../../infrastructure/adapters';
3
+ import { ChannelAgentAPI } from '../../../infrastructure/api';
4
+ import { GetChannelAgentsRequest } from '../../../infrastructure/interfaces/api';
5
+ import { IChannelAgent } from '../../interfaces';
2
6
  export default class ChannelAgentService extends IChannelAgent {
3
- constructor(channelAPI, channelAgentAdapter) {
7
+ constructor(_ref) {
8
+ let {
9
+ channelAgentAPI,
10
+ channelAgentAdapter,
11
+ httpClient
12
+ } = _ref;
4
13
  super();
5
- this.channelAPI = channelAPI;
6
- this.channelAgentAdapter = channelAgentAdapter;
14
+ this.channelAgentAPI = channelAgentAPI || new ChannelAgentAPI({
15
+ httpClient,
16
+ urlConfig: CHANNEL_AGENTS_API_URLS
17
+ });
18
+ this.channelAgentAdapter = channelAgentAdapter || new ChannelAgentAdapter();
7
19
  }
8
20
 
9
21
  async getChannelAgents() {
10
- const channelAgents = await this.channelAPI.getChannelAgents();
22
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GetChannelAgentsRequest;
23
+ const channelAgents = await this.channelAgentAPI.getChannelAgents(request);
11
24
  return channelAgents.map(this.channelAgentAdapter.adapt);
12
25
  }
13
26
 
@@ -0,0 +1,27 @@
1
+ import SESSIONS_API_URLS from '../../../config/urls/sessions/sessions-api-url';
2
+ import { SessionAdapter } from '../../../infrastructure/adapters';
3
+ import { SessionAPI } from '../../../infrastructure/api/sessions';
4
+ import { UpdateSessionAssigneeRequest } from '../../../infrastructure/interfaces/api';
5
+ import { ISession } from '../../interfaces';
6
+ export default class SessionService extends ISession {
7
+ constructor(_ref) {
8
+ let {
9
+ sessionAPI,
10
+ sessionAdapter,
11
+ httpClient
12
+ } = _ref;
13
+ super();
14
+ this.sessionAPI = sessionAPI || new SessionAPI({
15
+ httpClient,
16
+ urlConfig: SESSIONS_API_URLS
17
+ });
18
+ this.sessionAdapter = sessionAdapter || new SessionAdapter();
19
+ }
20
+
21
+ async updateAssignee() {
22
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : UpdateSessionAssigneeRequest;
23
+ const session = await this.sessionAPI.updateAssignee(request);
24
+ return this.channelAgentAdapter.adapt(session);
25
+ }
26
+
27
+ }
@@ -0,0 +1,2 @@
1
+ import SessionService from './SessionService';
2
+ export { SessionService };
package/es/index.js CHANGED
@@ -1 +1,8 @@
1
- export * from './domain';
1
+ export * from './domain/entities';
2
+ export * from './domain/enum';
3
+ export * from './domain/interfaces';
4
+ export * from './domain/services';
5
+ export * from './infrastructure/sdk';
6
+ export * from './infrastructure/adapters';
7
+ export * from './infrastructure/api';
8
+ export * from './infrastructure/interfaces/api';
@@ -0,0 +1,23 @@
1
+ import { AdapterError } from '../../core/errors';
2
+ /**
3
+ * Base adapter class that defines the contract for all adapters
4
+ * @abstract
5
+ */
6
+
7
+ export default class BaseAdapter {
8
+ /**
9
+ * Adapts the input data to required format
10
+ * @param {*} data - Data to adapt
11
+ * @throws {AdapterError} When method is not implemented
12
+ */
13
+ adapt(data) {
14
+ if (this.constructor === BaseAdapter) {
15
+ throw new AdapterError(`${this.constructor.name}: adapt() must be implemented by subclass`);
16
+ }
17
+
18
+ if (!data) {
19
+ throw new AdapterError(`${this.constructor.name}: data parameter is required`);
20
+ }
21
+ }
22
+
23
+ }
@@ -0,0 +1,35 @@
1
+ import BaseAdapter from '../BaseAdapter';
2
+ import { AdapterError } from '../../../core/errors';
3
+ import { Agent } from '../../../domain/entities';
4
+ /**
5
+ * Adapter for Channel Agent data
6
+ * @extends BaseAdapter
7
+ */
8
+
9
+ export default class ChannelAgentAdapter extends BaseAdapter {
10
+ /**
11
+ * Adapts channel agent data to Agent entity
12
+ * @param {Object} channelAgent - Channel agent data to adapt
13
+ * @returns {Object} Adapted agent data
14
+ * @throws {AdapterError} When adaptation fails
15
+ */
16
+ static adapt(channelAgent) {
17
+ if (!channelAgent) {
18
+ throw new AdapterError('Channel agent data is required');
19
+ }
20
+
21
+ try {
22
+ return new Agent({
23
+ id: channelAgent.id,
24
+ name: channelAgent.name,
25
+ email: channelAgent.email,
26
+ photoURL: channelAgent.photoURL || '',
27
+ zuid: channelAgent.zuid,
28
+ type: channelAgent.type
29
+ }).toJSON();
30
+ } catch (error) {
31
+ throw new AdapterError(`Failed to adapt channel agent: ${error.message}`);
32
+ }
33
+ }
34
+
35
+ }
@@ -0,0 +1,2 @@
1
+ import ChannelAgentAdapter from './ChannelAgentAdapter';
2
+ export { ChannelAgentAdapter };
@@ -0,0 +1,2 @@
1
+ export * from './channels';
2
+ export * from './sessions';
@@ -0,0 +1,37 @@
1
+ import BaseAdapter from '../BaseAdapter';
2
+ import { AdapterError } from '../../../core/errors';
3
+ import { Session } from '../../../domain/entities';
4
+ export default class SessionAdapter extends BaseAdapter {
5
+ static adapt(sessionData) {
6
+ if (!sessionData) {
7
+ throw new AdapterError('Session data is required');
8
+ }
9
+
10
+ try {
11
+ return new Session({
12
+ id: sessionData.id,
13
+ channelId: sessionData.channelId,
14
+ status: sessionData.status,
15
+ createdTime: sessionData.createdTime,
16
+ agentId: sessionData.agentId,
17
+ botId: sessionData.botId,
18
+ actor: sessionData.actor,
19
+ subject: sessionData.subject,
20
+ messagesCount: sessionData.messagesCount,
21
+ agentLastActiveTime: sessionData.agentLastActiveTime,
22
+ contactLastActiveTime: sessionData.contactLastActiveTime,
23
+ lastActiveTime: sessionData.lastActiveTime,
24
+ unreadMessagesCount: sessionData.unreadMessagesCount,
25
+ integrationServiceId: sessionData.integrationServiceId,
26
+ replyStatus: sessionData.replyStatus,
27
+ contactId: sessionData.contactId,
28
+ meta: sessionData.meta,
29
+ assignee: sessionData.assignee,
30
+ channel: sessionData.channel
31
+ }).toJSON();
32
+ } catch (error) {
33
+ throw new AdapterError(`Failed to adapt session: ${error.message}`);
34
+ }
35
+ }
36
+
37
+ }
@@ -0,0 +1,2 @@
1
+ import SessionAdapter from './SessionAdapter';
2
+ export { SessionAdapter };
@@ -0,0 +1,26 @@
1
+ import IChannelAgent from '../../../domain/interfaces/channels/IChannelAgent';
2
+ import { GetChannelAgentsRequest } from '../../interfaces/api';
3
+ export default class ChannelAgentAPI extends IChannelAgent {
4
+ constructor(_ref) {
5
+ let {
6
+ httpClient,
7
+ urlConfig
8
+ } = _ref;
9
+ super({
10
+ httpClient
11
+ });
12
+ this.httpClient = httpClient;
13
+ this.urlConfig = urlConfig;
14
+ }
15
+
16
+ async getChannelAgents() {
17
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GetChannelAgentsRequest;
18
+ const urlConfig = this.urlConfig.LIST;
19
+ const httpRequest = await this.request({
20
+ urlConfig,
21
+ request
22
+ });
23
+ return httpRequest;
24
+ }
25
+
26
+ }
@@ -0,0 +1,2 @@
1
+ import ChannelAgentAPI from './ChannelAgentAPI';
2
+ export { ChannelAgentAPI };
@@ -0,0 +1 @@
1
+ export * from './channels';
@@ -0,0 +1,25 @@
1
+ import { ISession } from '../../../domain/interfaces';
2
+ import { UpdateSessionAssigneeRequest } from '../../interfaces/api';
3
+ export default class SessionAPI extends ISession {
4
+ constructor(_ref) {
5
+ let {
6
+ httpClient,
7
+ urlConfig
8
+ } = _ref;
9
+ super({
10
+ httpClient
11
+ });
12
+ this.urlConfig = urlConfig;
13
+ }
14
+
15
+ async updateAssignee() {
16
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : UpdateSessionAssigneeRequest;
17
+ const urlConfig = this.urlConfig.UPDATE_SESSION_ASSIGNEE;
18
+ const httpRequest = await this.request({
19
+ urlConfig,
20
+ request
21
+ });
22
+ return httpRequest;
23
+ }
24
+
25
+ }
@@ -0,0 +1,2 @@
1
+ import SessionAPI from './SessionAPI';
2
+ export { SessionAPI };
@@ -0,0 +1,13 @@
1
+ const params = {
2
+ channelId: null
3
+ };
4
+ const query = {
5
+ from: 0,
6
+ limit: 10,
7
+ searchStr: null
8
+ };
9
+ const GetChannelAgentsRequest = {
10
+ params,
11
+ query
12
+ };
13
+ export default GetChannelAgentsRequest;
@@ -0,0 +1,2 @@
1
+ import GetChannelAgentsRequest from './GetChannelAgentsRequest';
2
+ export { GetChannelAgentsRequest };
@@ -0,0 +1 @@
1
+ export * from './agents';
@@ -0,0 +1,2 @@
1
+ export * from './channels';
2
+ export * from './sessions';
@@ -0,0 +1,12 @@
1
+ const params = {
2
+ sessionId: null
3
+ };
4
+ const query = {
5
+ agentId: null,
6
+ botId: null
7
+ };
8
+ const UpdateSessionAssigneeRequest = {
9
+ params,
10
+ query
11
+ };
12
+ export default UpdateSessionAssigneeRequest;
@@ -0,0 +1,2 @@
1
+ import UpdateSessionAssigneeRequest from './UpdateSessionAssigneeRequest';
2
+ export { UpdateSessionAssigneeRequest };
@@ -0,0 +1 @@
1
+ export * from './api';
@@ -0,0 +1,26 @@
1
+ import { ModuleNames } from '../../core/constants';
2
+ import { ChannelSDK } from '../sdk/channels';
3
+ import { SessionSDK } from '../sdk/sessions';
4
+ const ModuleFactory = {
5
+ [ModuleNames.CHANNELS]: _ref => {
6
+ let {
7
+ config,
8
+ httpClient
9
+ } = _ref;
10
+ return new ChannelSDK({
11
+ config,
12
+ httpClient
13
+ });
14
+ },
15
+ [ModuleNames.SESSIONS]: _ref2 => {
16
+ let {
17
+ config,
18
+ httpClient
19
+ } = _ref2;
20
+ return new SessionSDK({
21
+ config,
22
+ httpClient
23
+ });
24
+ }
25
+ };
26
+ export default ModuleFactory;
@@ -0,0 +1,46 @@
1
+ import ModuleFactory from './ModuleFactory';
2
+ export default class ModuleManager {
3
+ constructor() {
4
+ this._modules = new Map();
5
+ }
6
+
7
+ initialize(_ref) {
8
+ let {
9
+ config,
10
+ httpClient
11
+ } = _ref;
12
+ Object.entries(config).forEach(_ref2 => {
13
+ let [moduleName, moduleConfig] = _ref2;
14
+ this.initializeModule({
15
+ moduleName,
16
+ config: moduleConfig,
17
+ httpClient
18
+ });
19
+ });
20
+ }
21
+
22
+ initializeModule(_ref3) {
23
+ let {
24
+ moduleName,
25
+ config,
26
+ httpClient
27
+ } = _ref3;
28
+ const createModule = ModuleFactory[moduleName];
29
+
30
+ if (createModule) {
31
+ this._modules.set(moduleName, createModule({
32
+ config,
33
+ httpClient
34
+ }));
35
+ }
36
+ }
37
+
38
+ getModule(moduleName) {
39
+ return this._modules.get(moduleName);
40
+ }
41
+
42
+ hasModule(moduleName) {
43
+ return this._modules.has(moduleName);
44
+ }
45
+
46
+ }
@@ -0,0 +1,2 @@
1
+ import ModuleManager from './ModuleManager';
2
+ export { ModuleManager };
@@ -0,0 +1,29 @@
1
+ import { ModuleNames } from '../../core/constants';
2
+ import { ModuleManager } from '../managers';
3
+ export default class IMSDK {
4
+ constructor(_ref) {
5
+ let {
6
+ config = {},
7
+ httpClient
8
+ } = _ref;
9
+ this._moduleManager = new ModuleManager();
10
+
11
+ this._moduleManager.initialize({
12
+ config,
13
+ httpClient
14
+ });
15
+ }
16
+
17
+ get channels() {
18
+ return this._moduleManager.getModule(ModuleNames.CHANNELS);
19
+ }
20
+
21
+ get sessions() {
22
+ return this._moduleManager.getModule(ModuleNames.SESSIONS);
23
+ }
24
+
25
+ hasModule(moduleName) {
26
+ return this._modules.has(moduleName);
27
+ }
28
+
29
+ }
@@ -0,0 +1,22 @@
1
+ import { ChannelAgentService } from '../../../domain/services';
2
+ import { GetChannelAgentsRequest } from '../../interfaces/api';
3
+ export default class ChannelAgentsSDK {
4
+ constructor(_ref) {
5
+ let {
6
+ channelAgentAPI,
7
+ channelAgentAdapter,
8
+ httpClient
9
+ } = _ref;
10
+ this.channelAgentService = new ChannelAgentService({
11
+ channelAgentAPI,
12
+ channelAgentAdapter,
13
+ httpClient
14
+ });
15
+ }
16
+
17
+ async getAgents() {
18
+ let request = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GetChannelAgentsRequest;
19
+ return this.channelAgentService.getChannelAgents(request);
20
+ }
21
+
22
+ }
@@ -0,0 +1,19 @@
1
+ import ChannelAgentsSDK from './ChannelAgentsSDK';
2
+ export default class ChannelSDK {
3
+ constructor(_ref) {
4
+ let {
5
+ config,
6
+ httpClient
7
+ } = _ref;
8
+ const {
9
+ channelAgentAPI,
10
+ channelAgentAdapter
11
+ } = config;
12
+ this.agents = new ChannelAgentsSDK({
13
+ channelAgentAPI,
14
+ channelAgentAdapter,
15
+ httpClient
16
+ });
17
+ }
18
+
19
+ }
@@ -0,0 +1,2 @@
1
+ import ChannelSDK from './ChannelSDK';
2
+ export { ChannelSDK };
@@ -0,0 +1,2 @@
1
+ import IMSDK from './IMSDK';
2
+ export { IMSDK };
@@ -0,0 +1,22 @@
1
+ import { SessionService } from '../../../domain/services/sessions';
2
+
3
+ class SessionSDK extends SessionService {
4
+ constructor(_ref) {
5
+ let {
6
+ config,
7
+ httpClient
8
+ } = _ref;
9
+ const {
10
+ sessionAPI,
11
+ sessionAdapter
12
+ } = config;
13
+ super({
14
+ sessionAPI,
15
+ sessionAdapter,
16
+ httpClient
17
+ });
18
+ }
19
+
20
+ }
21
+
22
+ export default SessionSDK;
@@ -0,0 +1,2 @@
1
+ import SessionSDK from './SessionSDK';
2
+ export { SessionSDK };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohoim/client-sdk",
3
- "version": "1.0.0-poc1",
3
+ "version": "1.0.0-poc10",
4
4
  "description": "To have the client sdk for the IM",
5
5
  "main": "es/index.js",
6
6
  "module": "es/index.js",
@@ -10,12 +10,6 @@
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
13
- "exports": {
14
- ".": "./es/index.js",
15
- "./interfaces": "./es/interfaces/index.js",
16
- "./entities": "./es/entities/index.js",
17
- "./services": "./es/services/index.js"
18
- },
19
13
  "files": [
20
14
  "es",
21
15
  "!**/__tests__"
@@ -1,3 +0,0 @@
1
- export * from './entities';
2
- export * from './interfaces';
3
- export * from './services';
File without changes