@erxes/api-shared 3.2.21-1 → 3.2.22-1

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 (29) hide show
  1. package/core-modules/dist/erxes-api-shared-core-modules.cjs.dev.js +512 -8
  2. package/core-modules/dist/erxes-api-shared-core-modules.cjs.prod.js +512 -8
  3. package/core-modules/dist/erxes-api-shared-core-modules.esm.js +507 -10
  4. package/dist/declarations/src/core-modules/automations/conditionals.d.ts +59 -0
  5. package/dist/declarations/src/core-modules/automations/conditionals.d.ts.map +1 -0
  6. package/dist/declarations/src/core-modules/automations/definitions/executions.d.ts +10 -0
  7. package/dist/declarations/src/core-modules/automations/definitions/executions.d.ts.map +1 -1
  8. package/dist/declarations/src/core-modules/automations/index.d.ts +1 -0
  9. package/dist/declarations/src/core-modules/automations/index.d.ts.map +1 -1
  10. package/dist/declarations/src/core-modules/automations/zodTypes.d.ts +40 -0
  11. package/dist/declarations/src/core-modules/automations/zodTypes.d.ts.map +1 -1
  12. package/dist/declarations/src/core-modules/common/eventHandlers/createEventHandlers.d.ts.map +1 -1
  13. package/dist/declarations/src/core-modules/segments/joinChanges.d.ts +5 -1
  14. package/dist/declarations/src/core-modules/segments/joinChanges.d.ts.map +1 -1
  15. package/dist/{start-plugin-a2f6eca9.esm.js → start-plugin-2b3e89f5.esm.js} +73 -59
  16. package/dist/{start-plugin-b095acca.cjs.prod.js → start-plugin-46baacee.cjs.prod.js} +73 -58
  17. package/dist/{start-plugin-7dc096bc.cjs.dev.js → start-plugin-6687b329.cjs.dev.js} +73 -58
  18. package/package.json +1 -1
  19. package/src/core-modules/automations/conditionals.test.ts +302 -0
  20. package/src/core-modules/automations/conditionals.ts +403 -0
  21. package/src/core-modules/automations/definitions/executions.ts +3 -0
  22. package/src/core-modules/automations/index.ts +1 -0
  23. package/src/core-modules/automations/zodTypes.ts +1 -0
  24. package/src/core-modules/common/eventHandlers/createEventHandlers.ts +20 -2
  25. package/src/core-modules/segments/joinChanges.test.ts +62 -0
  26. package/src/core-modules/segments/joinChanges.ts +26 -11
  27. package/utils/dist/erxes-api-shared-utils.cjs.dev.js +1 -1
  28. package/utils/dist/erxes-api-shared-utils.cjs.prod.js +1 -1
  29. package/utils/dist/erxes-api-shared-utils.esm.js +2 -2
@@ -11,3 +11,4 @@ export * from './zodTypes';
11
11
  export * from './sendAutomationMessage';
12
12
  export * from './segmentMembership';
13
13
  export * from './reEnrollment';
14
+ export * from './conditionals';
@@ -28,6 +28,7 @@ export const AutomationExecActionInput = z.object({
28
28
  nextActionId: z.string().optional(),
29
29
  result: z.any().optional(),
30
30
  skipReason: z.string().optional(),
31
+ conditionalMatches: z.record(z.string()).optional(),
31
32
  attempt: z.number().optional(),
32
33
  jobId: z.string().optional(),
33
34
  // Dates arrive serialized across the producer boundary, but stay Date
@@ -15,7 +15,7 @@ import {
15
15
  } from './utils';
16
16
  import { sendAutomationTrigger } from '../../automations';
17
17
  import { sendSegmentChanged } from '../../segments/events';
18
- import { segmentJoinChanges } from '../../segments/joinChanges';
18
+ import { segmentJoinChanges, SegmentTouched } from '../../segments/joinChanges';
19
19
  import { INotificationData, sendNotification } from '../../notifications';
20
20
  import { logActivityLogError } from '../../logs/activityLog/utils';
21
21
 
@@ -25,6 +25,20 @@ const toIdList = (ids?: string | string[]): string[] =>
25
25
  (id): id is string => typeof id === 'string' && id.length > 0,
26
26
  );
27
27
 
28
+ /** The documents an action carried, before and after. */
29
+ const touchedOf = (input: LogEventInput): SegmentTouched => ({
30
+ prev: [
31
+ ...('prevDocument' in input && input.prevDocument
32
+ ? [input.prevDocument]
33
+ : []),
34
+ ...('prevDocuments' in input ? input.prevDocuments || [] : []),
35
+ ],
36
+ current:
37
+ 'currentDocument' in input && input.currentDocument
38
+ ? [input.currentDocument]
39
+ : [],
40
+ });
41
+
28
42
  /**
29
43
  * Create an event dispatcher instance with methods for logging and automation triggers
30
44
  * @param params - Configuration object for the event dispatcher
@@ -93,7 +107,11 @@ export function createEventHandlers(
93
107
  });
94
108
  const docIds = toIdList(eventPayload.docIds ?? eventPayload.docId);
95
109
 
96
- segmentJoinChanges(contentType, payload?.updateDescription)
110
+ segmentJoinChanges(
111
+ contentType,
112
+ payload?.updateDescription,
113
+ touchedOf(parsed),
114
+ )
97
115
  .then((changed) =>
98
116
  sendSegmentChanged({ subdomain, contentType, docIds, changed }),
99
117
  )
@@ -93,4 +93,66 @@ describe('segmentJoinChanges', () => {
93
93
  await segmentJoinChanges('core:contacts.customers', undefined),
94
94
  ).toBeUndefined();
95
95
  });
96
+ it('reaches the owner of a record created without a diff', async () => {
97
+ const changes = await segmentJoinChanges(
98
+ 'core:contacts.customers',
99
+ undefined,
100
+ { current: [{ _id: 'c1', ownerId: 'user_a' }] },
101
+ );
102
+
103
+ expect(changes).toEqual({ ownerId: { prev: undefined, next: ['user_a'] } });
104
+ });
105
+
106
+ it('reaches the owner when another field moved', async () => {
107
+ const changes = await segmentJoinChanges(
108
+ 'core:contacts.customers',
109
+ { updated: { primaryEmail: { prev: 'a@x.mn', current: 'b@x.mn' } } },
110
+ {
111
+ prev: [{ _id: 'c1', ownerId: 'user_a' }],
112
+ current: [{ _id: 'c1', ownerId: 'user_a' }],
113
+ },
114
+ );
115
+
116
+ expect(changes).toEqual({
117
+ ownerId: { prev: ['user_a'], next: ['user_a'] },
118
+ });
119
+ });
120
+
121
+ it('reaches both owners when the documents say it moved', async () => {
122
+ const changes = await segmentJoinChanges(
123
+ 'core:contacts.customers',
124
+ { updated: { ownerId: { prev: 'user_a', current: 'user_b' } } },
125
+ { current: [{ _id: 'c1', ownerId: 'user_b' }] },
126
+ );
127
+
128
+ expect(changes).toEqual({ ownerId: { prev: 'user_a', next: ['user_b'] } });
129
+ });
130
+
131
+ it('reaches the owner of a deleted record', async () => {
132
+ const changes = await segmentJoinChanges(
133
+ 'core:contacts.customers',
134
+ undefined,
135
+ { prev: [{ _id: 'c1', ownerId: 'user_a' }] },
136
+ );
137
+
138
+ expect(changes).toEqual({ ownerId: { prev: ['user_a'], next: undefined } });
139
+ });
140
+
141
+ it('collects every owner of a batch', async () => {
142
+ const changes = await segmentJoinChanges(
143
+ 'core:contacts.customers',
144
+ undefined,
145
+ {
146
+ current: [
147
+ { _id: 'c1', ownerId: 'user_a' },
148
+ { _id: 'c2' },
149
+ { _id: 'c3', ownerId: 'user_b' },
150
+ ],
151
+ },
152
+ );
153
+
154
+ expect(changes).toEqual({
155
+ ownerId: { prev: undefined, next: ['user_a', 'user_b'] },
156
+ });
157
+ });
96
158
  });
@@ -29,11 +29,24 @@ const isBothSides = (
29
29
  typeof value === 'object' &&
30
30
  ('prev' in (value as object) || 'current' in (value as object));
31
31
 
32
+ // The records a change touched, as they were and as they are.
33
+ export type SegmentTouched = { prev?: unknown[]; current?: unknown[] };
34
+
35
+ const valuesAt = (documents: unknown[] | undefined, path: string) => {
36
+ const values = (documents || []).flatMap((doc) => {
37
+ const value = at(doc, path);
38
+ return value === undefined ? [] : [value].flat();
39
+ });
40
+
41
+ return values.length ? values : undefined;
42
+ };
43
+
32
44
  export const segmentJoinChanges = async (
33
45
  contentType: string,
34
46
  diff: SegmentDiff | undefined,
47
+ touched: SegmentTouched = {},
35
48
  ): Promise<SegmentJoinChanges | undefined> => {
36
- if (!diff) {
49
+ if (!diff && !touched.prev?.length && !touched.current?.length) {
37
50
  return undefined;
38
51
  }
39
52
 
@@ -48,18 +61,20 @@ export const segmentJoinChanges = async (
48
61
  const changes: SegmentJoinChanges = {};
49
62
 
50
63
  for (const path of paths) {
51
- const updated = at(diff.updated, path);
52
-
53
- if (isBothSides(updated)) {
54
- changes[path] = { prev: updated.prev, next: updated.current };
55
- continue;
56
- }
64
+ const updated = at(diff?.updated, path);
65
+ const both = isBothSides(updated);
57
66
 
58
- const added = at(diff.added, path);
59
- const removed = at(diff.removed, path);
67
+ // A record reaches whoever it points at, whether or not that field moved;
68
+ // the diff only stands in where no document was at hand.
69
+ const prev =
70
+ valuesAt(touched.prev, path) ??
71
+ (both ? updated.prev : at(diff?.removed, path));
72
+ const next =
73
+ valuesAt(touched.current, path) ??
74
+ (both ? updated.current : at(diff?.added, path));
60
75
 
61
- if (added !== undefined || removed !== undefined) {
62
- changes[path] = { prev: removed, next: added };
76
+ if (prev !== undefined || next !== undefined) {
77
+ changes[path] = { prev, next };
63
78
  }
64
79
  }
65
80
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var startPlugin = require('../../dist/start-plugin-7dc096bc.cjs.dev.js');
5
+ var startPlugin = require('../../dist/start-plugin-6687b329.cjs.dev.js');
6
6
  var mongoose = require('mongoose');
7
7
  var stream$1 = require('stream');
8
8
  var _loadash = require('lodash');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var startPlugin = require('../../dist/start-plugin-b095acca.cjs.prod.js');
5
+ var startPlugin = require('../../dist/start-plugin-46baacee.cjs.prod.js');
6
6
  var mongoose = require('mongoose');
7
7
  var stream$1 = require('stream');
8
8
  var _loadash = require('lodash');
@@ -1,5 +1,5 @@
1
- import { u as userHeaderName, g as getEnv, c as connect, _ as _asyncToGenerator, a as _regeneratorRuntime, b as coreModelOrganizations, d as getSubdomain, e as getSaasCoreConnection, f as createScopedEventHandlers, h as _slicedToArray, l as logHandler, r as runBeforeResolvers, s as sendWorkerQueue, i as _objectSpread2, j as chunkArray, k as _createForOfIteratorHelper, m as _createClass, n as _classCallCheck, o as isValidURL, p as sendTRPCMessage, q as _inherits, t as _wrapNativeSuper, v as _callSuper, w as _defineProperty, x as _toConsumableArray } from '../../dist/start-plugin-a2f6eca9.esm.js';
2
- export { K as AGENT_TOOL_DEFAULT_MAX_RESPONSE_BYTES, ak as DEFAULT_JOB_OPTIONS, c1 as EXPECTED_ERROR_NAME, c2 as ExpectedError, aU as GP_STATUS, W as HEADER_SIZE_WARN_BYTES, bc as MAX_HEADER_BYTES, aA as ORGANIZATION_ID_MAPPING, T as TBeforeResolversProducers, V as USER_HEADER_OMITTED_FIELDS, N as agentToolResponseTooLargeError, F as agentToolsAuthHeaderName, y as apolloCustomScalars, bn as applyTrustProxy, bp as authCookieOptions, I as buildAgentToolManifest, bW as buildCursorQuery, ag as buildSearchTokenFilter, D as checkBeforeResolvers, aa as checkCollectionCodeDuplication, bM as checkServiceRunning, by as checkUserIds, j as chunkArray, c4 as classifyError, b$ as cleanHtml, b5 as clearServiceDiscoveryCache, P as clientPortalHeaderName, ad as closeMongooose, X as compactUserForHeader, ah as configureSchemaSearchTokens, c as connect, bo as connectionOptions, ar as coreModelAddons, as as coreModelBundles, av as coreModelEndpoints, ay as coreModelExperiences, at as coreModelInstallations, az as coreModelOrganizationPlanHistories, b as coreModelOrganizations, ax as coreModelPlugins, aw as coreModelPromoCodes, au as coreModelUsers, Q as cpUserHeaderName, c3 as createExpectedError, bL as createHealthRoute, al as createMQWorkerWithListeners, bh as createPluginTRPCContext, bi as createTRPCContext, a8 as cursorPaginate, a9 as cursorPaginateAggregation, bH as dateToShortStr, H as decodeAgentToolsAuthHeader, bV as decodeCursor, bg as decodeTRPCContextHeader, a7 as defaultPaginate, G as encodeAgentToolsAuthHeader, bU as encodeCursor, bf as encodeTRPCContextHeader, bk as err, bu as escapeRegExp, E as expectedErrorPlugin, S as extractCPUserFromHeader, U as extractClientPortalFromHeader, c6 as extractMessage, R as extractUserFromHeader, bx as fixDate, bG as fixNum, bP as flattenObject, z as generateApolloContext, af as generateConfiguredSearchTokens, bN as generateRequestProcess, b3 as getActivePlugins, L as getAgentToolMaxResponseBytes, b4 as getAvailablePlugins, bt as getCoreDomain, bA as getDate, bO as getDiffObjects, g as getEnv, bC as getFullDate, aY as getGlobalProfileV2Plugins, bF as getNextMonth, b6 as getPlugin, ba as getPluginAddress, b1 as getPlugins, bD as getPureDate, e as getSaasCoreConnection, aT as getSaasOrgPromoCodes, aO as getSaasOrganizationActiveAddons, aH as getSaasOrganizationByHelpCenterDomain, aM as getSaasOrganizationDetail, aI as getSaasOrganizationHelpCenterDomains, aB as getSaasOrganizationIdBySubdomain, aN as getSaasOrganizationPlanHistories, aD as getSaasOrganizations, aE as getSaasOrganizationsByFilter, aJ as getSaasOrganizationsWithPendingHelpCenterDomain, aC as getSaasOrgsCache, aR as getSaasPlugin, aQ as getSaasPlugins, aS as getSaasPromoCodes, ai as getSchemaSearchTokenConfig, d as getSubdomain, bB as getToday, bE as getTomorrow, bm as getTrustProxySetting, bz as getUniqueValue, O as graphqlPubsub, aG as helpCenterDomainsOf, c8 as initErxesSentry, bb as initializePluginConfig, a$ as isDev, b9 as isEnabled, c5 as isExpectedError, aV as isGlobalProfileV2, bJ as isImage, o as isValidURL, bK as isVideo, b7 as joinErxesGateway, b0 as keyForConfig, b8 as leaveErxesGateway, l as logHandler, B as markResolvers, a3 as mongoStringRequired, ac as mongooseConnectionOptions, a5 as mongooseField, a2 as mongooseStringNonBlank, a1 as mongooseStringRandomId, a4 as mongooseStringRequiredNonBlank, J as mountAgentTools, bj as ok, M as oversizedAgentToolResultBytes, bq as paginate, aX as pluginsFromStripe, aW as pluginsOfStripeItem, bw as pluralFormation, c0 as random, an as randomAlphanumeric, ao as randomLowercase, bR as readFileFromStorage, bS as readFileStreamFromStorage, bQ as readFileUrl, ap as redis, bs as regexSearchText, bZ as removeExtraSpaces, bY as removeLastTrailingSlash, aP as removeOrgsCache, aL as removeSaasOrganizationHelpCenterDomain, aq as resetConfigsCache, r as runBeforeResolvers, aZ as sanitizeFilename, a_ as sanitizeKey, aK as saveSaasOrganizationHelpCenterDomain, ab as schemaWrapper, bl as sendCoreModuleProducer, p as sendTRPCMessage, am as sendWorkerMessage, s as sendWorkerQueue, c7 as sentryExpectedErrorFilter, b2 as setActivePlugins, Z as setCPUserHeader, $ as setClientPortalHeader, Y as setUserHeader, bI as shortStrToDate, ae as splitSearchWords, b_ as splitStr, a0 as startAfterProcess, C as startBeforeResolvers, bd as startPlugin, bX as stripAnsi, aj as toSerializablePayload, be as trpcContextHeaderName, a6 as updateMongoDocumentOrder, bv as updateOrder, aF as updateSaasOrganization, bT as uploadFileToStorage, u as userHeaderName, br as validSearchText, A as wrapApolloResolvers } from '../../dist/start-plugin-a2f6eca9.esm.js';
1
+ import { u as userHeaderName, g as getEnv, c as connect, _ as _asyncToGenerator, a as _regeneratorRuntime, b as coreModelOrganizations, d as getSubdomain, e as getSaasCoreConnection, f as createScopedEventHandlers, h as _slicedToArray, l as logHandler, r as runBeforeResolvers, s as sendWorkerQueue, i as _objectSpread2, j as chunkArray, k as _createForOfIteratorHelper, m as _createClass, n as _classCallCheck, o as isValidURL, p as sendTRPCMessage, q as _inherits, t as _wrapNativeSuper, v as _callSuper, w as _defineProperty, x as _toConsumableArray } from '../../dist/start-plugin-2b3e89f5.esm.js';
2
+ export { K as AGENT_TOOL_DEFAULT_MAX_RESPONSE_BYTES, ak as DEFAULT_JOB_OPTIONS, c1 as EXPECTED_ERROR_NAME, c2 as ExpectedError, aU as GP_STATUS, W as HEADER_SIZE_WARN_BYTES, bc as MAX_HEADER_BYTES, aA as ORGANIZATION_ID_MAPPING, T as TBeforeResolversProducers, V as USER_HEADER_OMITTED_FIELDS, N as agentToolResponseTooLargeError, F as agentToolsAuthHeaderName, y as apolloCustomScalars, bn as applyTrustProxy, bp as authCookieOptions, I as buildAgentToolManifest, bW as buildCursorQuery, ag as buildSearchTokenFilter, D as checkBeforeResolvers, aa as checkCollectionCodeDuplication, bM as checkServiceRunning, by as checkUserIds, j as chunkArray, c4 as classifyError, b$ as cleanHtml, b5 as clearServiceDiscoveryCache, P as clientPortalHeaderName, ad as closeMongooose, X as compactUserForHeader, ah as configureSchemaSearchTokens, c as connect, bo as connectionOptions, ar as coreModelAddons, as as coreModelBundles, av as coreModelEndpoints, ay as coreModelExperiences, at as coreModelInstallations, az as coreModelOrganizationPlanHistories, b as coreModelOrganizations, ax as coreModelPlugins, aw as coreModelPromoCodes, au as coreModelUsers, Q as cpUserHeaderName, c3 as createExpectedError, bL as createHealthRoute, al as createMQWorkerWithListeners, bh as createPluginTRPCContext, bi as createTRPCContext, a8 as cursorPaginate, a9 as cursorPaginateAggregation, bH as dateToShortStr, H as decodeAgentToolsAuthHeader, bV as decodeCursor, bg as decodeTRPCContextHeader, a7 as defaultPaginate, G as encodeAgentToolsAuthHeader, bU as encodeCursor, bf as encodeTRPCContextHeader, bk as err, bu as escapeRegExp, E as expectedErrorPlugin, S as extractCPUserFromHeader, U as extractClientPortalFromHeader, c6 as extractMessage, R as extractUserFromHeader, bx as fixDate, bG as fixNum, bP as flattenObject, z as generateApolloContext, af as generateConfiguredSearchTokens, bN as generateRequestProcess, b3 as getActivePlugins, L as getAgentToolMaxResponseBytes, b4 as getAvailablePlugins, bt as getCoreDomain, bA as getDate, bO as getDiffObjects, g as getEnv, bC as getFullDate, aY as getGlobalProfileV2Plugins, bF as getNextMonth, b6 as getPlugin, ba as getPluginAddress, b1 as getPlugins, bD as getPureDate, e as getSaasCoreConnection, aT as getSaasOrgPromoCodes, aO as getSaasOrganizationActiveAddons, aH as getSaasOrganizationByHelpCenterDomain, aM as getSaasOrganizationDetail, aI as getSaasOrganizationHelpCenterDomains, aB as getSaasOrganizationIdBySubdomain, aN as getSaasOrganizationPlanHistories, aD as getSaasOrganizations, aE as getSaasOrganizationsByFilter, aJ as getSaasOrganizationsWithPendingHelpCenterDomain, aC as getSaasOrgsCache, aR as getSaasPlugin, aQ as getSaasPlugins, aS as getSaasPromoCodes, ai as getSchemaSearchTokenConfig, d as getSubdomain, bB as getToday, bE as getTomorrow, bm as getTrustProxySetting, bz as getUniqueValue, O as graphqlPubsub, aG as helpCenterDomainsOf, c8 as initErxesSentry, bb as initializePluginConfig, a$ as isDev, b9 as isEnabled, c5 as isExpectedError, aV as isGlobalProfileV2, bJ as isImage, o as isValidURL, bK as isVideo, b7 as joinErxesGateway, b0 as keyForConfig, b8 as leaveErxesGateway, l as logHandler, B as markResolvers, a3 as mongoStringRequired, ac as mongooseConnectionOptions, a5 as mongooseField, a2 as mongooseStringNonBlank, a1 as mongooseStringRandomId, a4 as mongooseStringRequiredNonBlank, J as mountAgentTools, bj as ok, M as oversizedAgentToolResultBytes, bq as paginate, aX as pluginsFromStripe, aW as pluginsOfStripeItem, bw as pluralFormation, c0 as random, an as randomAlphanumeric, ao as randomLowercase, bR as readFileFromStorage, bS as readFileStreamFromStorage, bQ as readFileUrl, ap as redis, bs as regexSearchText, bZ as removeExtraSpaces, bY as removeLastTrailingSlash, aP as removeOrgsCache, aL as removeSaasOrganizationHelpCenterDomain, aq as resetConfigsCache, r as runBeforeResolvers, aZ as sanitizeFilename, a_ as sanitizeKey, aK as saveSaasOrganizationHelpCenterDomain, ab as schemaWrapper, bl as sendCoreModuleProducer, p as sendTRPCMessage, am as sendWorkerMessage, s as sendWorkerQueue, c7 as sentryExpectedErrorFilter, b2 as setActivePlugins, Z as setCPUserHeader, $ as setClientPortalHeader, Y as setUserHeader, bI as shortStrToDate, ae as splitSearchWords, b_ as splitStr, a0 as startAfterProcess, C as startBeforeResolvers, bd as startPlugin, bX as stripAnsi, aj as toSerializablePayload, be as trpcContextHeaderName, a6 as updateMongoDocumentOrder, bv as updateOrder, aF as updateSaasOrganization, bT as uploadFileToStorage, u as userHeaderName, br as validSearchText, A as wrapApolloResolvers } from '../../dist/start-plugin-2b3e89f5.esm.js';
3
3
  import mongoose from 'mongoose';
4
4
  import { Transform } from 'stream';
5
5
  import { keyBy } from 'lodash';