@mj-biz-apps/common-activity-sync 0.0.0 → 5.37.0
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.
- package/dist/ActivitySyncEngine.d.ts +118 -0
- package/dist/ActivitySyncEngine.d.ts.map +1 -0
- package/dist/ActivitySyncEngine.js +620 -0
- package/dist/ActivitySyncEngine.js.map +1 -0
- package/dist/BaseActivitySyncExtension.d.ts +99 -0
- package/dist/BaseActivitySyncExtension.d.ts.map +1 -0
- package/dist/BaseActivitySyncExtension.js +3 -0
- package/dist/BaseActivitySyncExtension.js.map +1 -0
- package/dist/BaseActivitySyncProvider.d.ts +40 -0
- package/dist/BaseActivitySyncProvider.d.ts.map +1 -0
- package/dist/BaseActivitySyncProvider.js +76 -0
- package/dist/BaseActivitySyncProvider.js.map +1 -0
- package/dist/action-result.d.ts +38 -0
- package/dist/action-result.d.ts.map +1 -0
- package/dist/action-result.js +43 -0
- package/dist/action-result.js.map +1 -0
- package/dist/entity-names.d.ts +19 -0
- package/dist/entity-names.d.ts.map +1 -0
- package/dist/entity-names.js +19 -0
- package/dist/entity-names.js.map +1 -0
- package/dist/extensions.d.ts +37 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +80 -0
- package/dist/extensions.js.map +1 -0
- package/dist/identity.d.ts +30 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +90 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/load.d.ts +17 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +29 -0
- package/dist/load.js.map +1 -0
- package/dist/manual-log.d.ts +33 -0
- package/dist/manual-log.d.ts.map +1 -0
- package/dist/manual-log.js +230 -0
- package/dist/manual-log.js.map +1 -0
- package/dist/participants.d.ts +47 -0
- package/dist/participants.d.ts.map +1 -0
- package/dist/participants.js +59 -0
- package/dist/participants.js.map +1 -0
- package/dist/providers/FixtureActivitySyncProvider.d.ts +21 -0
- package/dist/providers/FixtureActivitySyncProvider.d.ts.map +1 -0
- package/dist/providers/FixtureActivitySyncProvider.js +58 -0
- package/dist/providers/FixtureActivitySyncProvider.js.map +1 -0
- package/dist/providers/GraphMessageMapper.d.ts +37 -0
- package/dist/providers/GraphMessageMapper.d.ts.map +1 -0
- package/dist/providers/GraphMessageMapper.js +91 -0
- package/dist/providers/GraphMessageMapper.js.map +1 -0
- package/dist/providers/MSGraphActivitySyncProvider.d.ts +22 -0
- package/dist/providers/MSGraphActivitySyncProvider.d.ts.map +1 -0
- package/dist/providers/MSGraphActivitySyncProvider.js +62 -0
- package/dist/providers/MSGraphActivitySyncProvider.js.map +1 -0
- package/dist/providers/MSGraphCalendarSyncProvider.d.ts +60 -0
- package/dist/providers/MSGraphCalendarSyncProvider.d.ts.map +1 -0
- package/dist/providers/MSGraphCalendarSyncProvider.js +145 -0
- package/dist/providers/MSGraphCalendarSyncProvider.js.map +1 -0
- package/dist/qualification.d.ts +91 -0
- package/dist/qualification.d.ts.map +1 -0
- package/dist/qualification.js +62 -0
- package/dist/qualification.js.map +1 -0
- package/dist/run.d.ts +67 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +84 -0
- package/dist/run.js.map +1 -0
- package/dist/sql.d.ts +17 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +50 -0
- package/dist/sql.js.map +1 -0
- package/dist/stages.d.ts +55 -0
- package/dist/stages.d.ts.map +1 -0
- package/dist/stages.js +109 -0
- package/dist/stages.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +38 -0
- package/dist/types.js.map +1 -0
- package/dist/watermark.d.ts +63 -0
- package/dist/watermark.d.ts.map +1 -0
- package/dist/watermark.js +103 -0
- package/dist/watermark.js.map +1 -0
- package/dist/writer.d.ts +132 -0
- package/dist/writer.d.ts.map +1 -0
- package/dist/writer.js +326 -0
- package/dist/writer.js.map +1 -0
- package/package.json +32 -5
- package/README.md +0 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mj-biz-apps/common-activity-sync
|
|
3
|
+
*
|
|
4
|
+
* Contracts for the Activity Sync Engine: the provider plugin base class, the qualification
|
|
5
|
+
* cascade, and the in-process extension contract downstream apps implement to enrich an Activity
|
|
6
|
+
* inside its own write transaction.
|
|
7
|
+
*
|
|
8
|
+
* Design: plans/activity-sync-engine.md
|
|
9
|
+
*/
|
|
10
|
+
export * from './types.js';
|
|
11
|
+
export * from './watermark.js';
|
|
12
|
+
export * from './qualification.js';
|
|
13
|
+
export * from './participants.js';
|
|
14
|
+
export * from './run.js';
|
|
15
|
+
export * from './BaseActivitySyncProvider.js';
|
|
16
|
+
export * from './BaseActivitySyncExtension.js';
|
|
17
|
+
export * from './entity-names.js';
|
|
18
|
+
export * from './identity.js';
|
|
19
|
+
export * from './writer.js';
|
|
20
|
+
export * from './manual-log.js';
|
|
21
|
+
export * from './stages.js';
|
|
22
|
+
export * from './ActivitySyncEngine.js';
|
|
23
|
+
export * from './action-result.js';
|
|
24
|
+
export * from './extensions.js';
|
|
25
|
+
export * from './providers/FixtureActivitySyncProvider.js';
|
|
26
|
+
export * from './providers/MSGraphActivitySyncProvider.js';
|
|
27
|
+
export * from './providers/MSGraphCalendarSyncProvider.js';
|
|
28
|
+
export * from './providers/GraphMessageMapper.js';
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mj-biz-apps/common-activity-sync
|
|
3
|
+
*
|
|
4
|
+
* Contracts for the Activity Sync Engine: the provider plugin base class, the qualification
|
|
5
|
+
* cascade, and the in-process extension contract downstream apps implement to enrich an Activity
|
|
6
|
+
* inside its own write transaction.
|
|
7
|
+
*
|
|
8
|
+
* Design: plans/activity-sync-engine.md
|
|
9
|
+
*/
|
|
10
|
+
export * from './types.js';
|
|
11
|
+
export * from './watermark.js';
|
|
12
|
+
export * from './qualification.js';
|
|
13
|
+
export * from './participants.js';
|
|
14
|
+
export * from './run.js';
|
|
15
|
+
export * from './BaseActivitySyncProvider.js';
|
|
16
|
+
export * from './BaseActivitySyncExtension.js';
|
|
17
|
+
export * from './entity-names.js';
|
|
18
|
+
export * from './identity.js';
|
|
19
|
+
export * from './writer.js';
|
|
20
|
+
export * from './manual-log.js';
|
|
21
|
+
export * from './stages.js';
|
|
22
|
+
export * from './ActivitySyncEngine.js';
|
|
23
|
+
export * from './action-result.js';
|
|
24
|
+
export * from './extensions.js';
|
|
25
|
+
export * from './providers/FixtureActivitySyncProvider.js';
|
|
26
|
+
export * from './providers/MSGraphActivitySyncProvider.js';
|
|
27
|
+
export * from './providers/MSGraphCalendarSyncProvider.js';
|
|
28
|
+
export * from './providers/GraphMessageMapper.js';
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC"}
|
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ViewLoad<T> = {
|
|
2
|
+
Failed: true;
|
|
3
|
+
Issue: string;
|
|
4
|
+
} | {
|
|
5
|
+
Failed: false;
|
|
6
|
+
Rows: T[];
|
|
7
|
+
};
|
|
8
|
+
export declare function FromRunView<T>(success: boolean, results: readonly T[] | null | undefined, what: string): ViewLoad<T>;
|
|
9
|
+
/** Global exclusions plus those bound to the connection's rule sets. */
|
|
10
|
+
export declare function ExclusionsExtraFilter(setIds: readonly string[]): string;
|
|
11
|
+
/**
|
|
12
|
+
* Bound rule-set ids on success. Empty ids fall through to the deprecated
|
|
13
|
+
* connection-owned rules. A failed binding read must not take that fallthrough —
|
|
14
|
+
* that would load the wrong rules.
|
|
15
|
+
*/
|
|
16
|
+
export declare function RulesExtraFilter(setIds: readonly string[], connectionID: string): string;
|
|
17
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,CAAC,EAAE,CAAA;CAAE,CAAC;AAEzF,wBAAgB,WAAW,CAAC,CAAC,EACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EACxC,IAAI,EAAE,MAAM,GACb,QAAQ,CAAC,CAAC,CAAC,CAGb;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIvE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKxF"}
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunView results. A failed read is not an empty list — those two look the same
|
|
3
|
+
* and only one may advance a watermark or decide an exclusion.
|
|
4
|
+
*/
|
|
5
|
+
import { RequireUUID, UuidInList } from './sql.js';
|
|
6
|
+
export function FromRunView(success, results, what) {
|
|
7
|
+
if (!success)
|
|
8
|
+
return { Failed: true, Issue: `${what} lookup failed.` };
|
|
9
|
+
return { Failed: false, Rows: [...(results ?? [])] };
|
|
10
|
+
}
|
|
11
|
+
/** Global exclusions plus those bound to the connection's rule sets. */
|
|
12
|
+
export function ExclusionsExtraFilter(setIds) {
|
|
13
|
+
const global = 'ActivitySyncRuleSetID IS NULL';
|
|
14
|
+
if (setIds.length === 0)
|
|
15
|
+
return global;
|
|
16
|
+
return `(${global} OR ActivitySyncRuleSetID IN (${UuidInList(setIds, 'ActivitySyncRuleSetID')}))`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Bound rule-set ids on success. Empty ids fall through to the deprecated
|
|
20
|
+
* connection-owned rules. A failed binding read must not take that fallthrough —
|
|
21
|
+
* that would load the wrong rules.
|
|
22
|
+
*/
|
|
23
|
+
export function RulesExtraFilter(setIds, connectionID) {
|
|
24
|
+
if (setIds.length > 0) {
|
|
25
|
+
return `ActivitySyncRuleSetID IN (${UuidInList(setIds, 'ActivitySyncRuleSetID')})`;
|
|
26
|
+
}
|
|
27
|
+
return `ActivitySyncConnectionID = '${RequireUUID(connectionID, 'ActivitySyncConnectionID')}'`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=load.js.map
|
package/dist/load.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,UAAU,WAAW,CACvB,OAAgB,EAChB,OAAwC,EACxC,IAAY;IAEZ,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACvE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,qBAAqB,CAAC,MAAyB;IAC3D,MAAM,MAAM,GAAG,+BAA+B,CAAC;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACvC,OAAO,IAAI,MAAM,iCAAiC,UAAU,CAAC,MAAM,EAAE,uBAAuB,CAAC,IAAI,CAAC;AACtG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAyB,EAAE,YAAoB;IAC5E,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,6BAA6B,UAAU,CAAC,MAAM,EAAE,uBAAuB,CAAC,GAAG,CAAC;IACvF,CAAC;IACD,OAAO,+BAA+B,WAAW,CAAC,YAAY,EAAE,0BAA0B,CAAC,GAAG,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ActivityLinkRole } from './types.js';
|
|
2
|
+
import type { WriteManualActivityInput } from './writer.js';
|
|
3
|
+
/** The SourceSystem stamped on idempotent declarative writes when a binding sets EventKey alone. */
|
|
4
|
+
export declare const LOG_ACTIVITY_DEFAULT_SOURCE_SYSTEM = "EntityAction";
|
|
5
|
+
/**
|
|
6
|
+
* Declarative "link the activity to whatever this record points at": read `Field` from
|
|
7
|
+
* `RecordData` and, when it holds a value, link that record with `Role`. This is what makes
|
|
8
|
+
* timeline population configuration — a binding on any entity can route the activity to the
|
|
9
|
+
* People / Organizations rows the record references, with no code in the consuming app.
|
|
10
|
+
*/
|
|
11
|
+
export interface LogActivityLinkFieldSpec {
|
|
12
|
+
Field: string;
|
|
13
|
+
EntityName: string;
|
|
14
|
+
Role: ActivityLinkRole;
|
|
15
|
+
}
|
|
16
|
+
export interface LogActivityParseResult {
|
|
17
|
+
Input: WriteManualActivityInput | null;
|
|
18
|
+
Errors: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse the flat parameter set of `Common.LogActivity` into a `WriteManualActivityInput`.
|
|
22
|
+
*
|
|
23
|
+
* Conveniences for declarative bindings:
|
|
24
|
+
* - `EntityName` + `RecordID` (or `RecordData.ID`) become a leading `Regarding` link — the record
|
|
25
|
+
* the activity is about.
|
|
26
|
+
* - `LinkFields` routes the activity to records the subject points at (see the type's doc).
|
|
27
|
+
* - `EventKey` makes a binding idempotent per record: with `EntityName` and a record id present,
|
|
28
|
+
* `ExternalID` becomes `EntityName|RecordID|EventKey` and `SourceSystem` defaults to
|
|
29
|
+
* 'EntityAction', so a durable retry cannot double-log. Use it for one-per-record events
|
|
30
|
+
* (AfterCreate); leave it off when every firing should log (a status that changes repeatedly).
|
|
31
|
+
*/
|
|
32
|
+
export declare function ParseLogActivityParams(values: Record<string, unknown>): LogActivityParseResult;
|
|
33
|
+
//# sourceMappingURL=manual-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-log.d.ts","sourceRoot":"","sources":["../src/manual-log.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAA2C,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,KAAK,EAKR,wBAAwB,EAC3B,MAAM,aAAa,CAAC;AAErB,oGAAoG;AACpG,eAAO,MAAM,kCAAkC,iBAAiB,CAAC;AAOjE;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAiJD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,sBAAsB,CAgE9F"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter parsing for `Common.LogActivity` — the declarative entry point to the unified timeline.
|
|
3
|
+
*
|
|
4
|
+
* Everything here takes PLAIN, SERIALIZABLE values, because the action's inputs may cross a queue,
|
|
5
|
+
* a durable task or an agent boundary before they arrive. That is why an Entity Action binding must
|
|
6
|
+
* feed `RecordData` with ValueType `'Entity Object Data'` and never `'Entity Object'`: a
|
|
7
|
+
* `BaseEntity` serializes to `{}` (its fields are getters, not enumerable own properties) —
|
|
8
|
+
* silently, with no error (plans/mj-entity-action-workflow-adoption.md §3.3).
|
|
9
|
+
*
|
|
10
|
+
* Pure functions, no I/O — the `Common.LogActivity` action in `@mj-biz-apps/common-server` is a
|
|
11
|
+
* thin shell over `ParseLogActivityParams` + `ActivityWriter.WriteManual`.
|
|
12
|
+
*/
|
|
13
|
+
import { ACTIVITY_IDENTITY_KINDS, ACTIVITY_LINK_ROLES } from './types.js';
|
|
14
|
+
/** The SourceSystem stamped on idempotent declarative writes when a binding sets EventKey alone. */
|
|
15
|
+
export const LOG_ACTIVITY_DEFAULT_SOURCE_SYSTEM = 'EntityAction';
|
|
16
|
+
const DIRECTIONS = ['Inbound', 'Outbound', 'Internal'];
|
|
17
|
+
const STATUSES = ['Logged', 'Scheduled', 'Completed', 'Cancelled', 'Failed'];
|
|
18
|
+
const VISIBILITIES = ['Internal', 'Private'];
|
|
19
|
+
const SOURCES = ['Manual', 'System'];
|
|
20
|
+
class ParamReader {
|
|
21
|
+
constructor(values) {
|
|
22
|
+
this.byName = new Map();
|
|
23
|
+
this.errors = [];
|
|
24
|
+
for (const [name, value] of Object.entries(values)) {
|
|
25
|
+
this.byName.set(name.toLowerCase(), value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
raw(name) {
|
|
29
|
+
const value = this.byName.get(name.toLowerCase());
|
|
30
|
+
return value === null || value === undefined || value === '' ? undefined : value;
|
|
31
|
+
}
|
|
32
|
+
string(name) {
|
|
33
|
+
const value = this.raw(name);
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (typeof value !== 'string') {
|
|
37
|
+
this.errors.push(`${name} must be a string.`);
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const trimmed = value.trim();
|
|
41
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
42
|
+
}
|
|
43
|
+
date(name) {
|
|
44
|
+
const value = this.raw(name);
|
|
45
|
+
if (value === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
const parsed = value instanceof Date ? value : typeof value === 'string' ? new Date(value) : undefined;
|
|
48
|
+
if (!parsed || Number.isNaN(parsed.getTime())) {
|
|
49
|
+
this.errors.push(`${name} must be a date or an ISO date string.`);
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
oneOf(name, allowed) {
|
|
55
|
+
const value = this.string(name);
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const match = allowed.find((candidate) => candidate.toLowerCase() === value.toLowerCase());
|
|
59
|
+
if (!match) {
|
|
60
|
+
this.errors.push(`${name} must be one of: ${allowed.join(', ')}.`);
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return match;
|
|
64
|
+
}
|
|
65
|
+
/** An object param that may arrive as a real object or as a JSON string. */
|
|
66
|
+
object(name) {
|
|
67
|
+
const value = this.raw(name);
|
|
68
|
+
if (value === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
if (typeof value === 'object')
|
|
71
|
+
return value;
|
|
72
|
+
if (typeof value === 'string') {
|
|
73
|
+
try {
|
|
74
|
+
return JSON.parse(value);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
this.errors.push(`${name} must be an object or valid JSON.`);
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
this.errors.push(`${name} must be an object or valid JSON.`);
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isRecord(value) {
|
|
86
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
87
|
+
}
|
|
88
|
+
function parseLinkSpecs(reader) {
|
|
89
|
+
const value = reader.object('Links');
|
|
90
|
+
if (value === undefined)
|
|
91
|
+
return [];
|
|
92
|
+
if (!Array.isArray(value)) {
|
|
93
|
+
reader.errors.push('Links must be an array of link specs.');
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const links = [];
|
|
97
|
+
for (const [index, item] of value.entries()) {
|
|
98
|
+
const link = parseOneLinkSpec(item, index, reader.errors);
|
|
99
|
+
if (link)
|
|
100
|
+
links.push(link);
|
|
101
|
+
}
|
|
102
|
+
return links;
|
|
103
|
+
}
|
|
104
|
+
function parseOneLinkSpec(item, index, errors) {
|
|
105
|
+
if (!isRecord(item)) {
|
|
106
|
+
errors.push(`Links[${index}] must be an object.`);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const role = item.Role;
|
|
110
|
+
if (typeof role !== 'string' || !ACTIVITY_LINK_ROLES.includes(role)) {
|
|
111
|
+
errors.push(`Links[${index}].Role must be one of: ${ACTIVITY_LINK_ROLES.join(', ')}.`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const kind = item.IdentityKind;
|
|
115
|
+
if (kind !== undefined && (typeof kind !== 'string' || !ACTIVITY_IDENTITY_KINDS.includes(kind))) {
|
|
116
|
+
errors.push(`Links[${index}].IdentityKind must be one of: ${ACTIVITY_IDENTITY_KINDS.join(', ')}.`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
Role: role,
|
|
121
|
+
EntityName: typeof item.EntityName === 'string' ? item.EntityName : undefined,
|
|
122
|
+
RecordID: typeof item.RecordID === 'string' ? item.RecordID : undefined,
|
|
123
|
+
IdentityKind: kind,
|
|
124
|
+
IdentityValue: typeof item.IdentityValue === 'string' ? item.IdentityValue : undefined,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function parseLinkFields(reader, recordData) {
|
|
128
|
+
const value = reader.object('LinkFields');
|
|
129
|
+
if (value === undefined)
|
|
130
|
+
return [];
|
|
131
|
+
if (!Array.isArray(value)) {
|
|
132
|
+
reader.errors.push('LinkFields must be an array of { Field, EntityName, Role } specs.');
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
if (!recordData) {
|
|
136
|
+
reader.errors.push('LinkFields requires RecordData to read the fields from.');
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
const links = [];
|
|
140
|
+
for (const [index, item] of value.entries()) {
|
|
141
|
+
if (!isRecord(item) || typeof item.Field !== 'string' || typeof item.EntityName !== 'string') {
|
|
142
|
+
reader.errors.push(`LinkFields[${index}] must carry Field, EntityName and Role.`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const role = item.Role;
|
|
146
|
+
if (typeof role !== 'string' || !ACTIVITY_LINK_ROLES.includes(role)) {
|
|
147
|
+
reader.errors.push(`LinkFields[${index}].Role must be one of: ${ACTIVITY_LINK_ROLES.join(', ')}.`);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const target = recordData[item.Field];
|
|
151
|
+
if (typeof target === 'string' && target.trim().length > 0) {
|
|
152
|
+
links.push({ Role: role, EntityName: item.EntityName, RecordID: target });
|
|
153
|
+
}
|
|
154
|
+
// A null / absent FK is not an error — the record simply does not point at anything.
|
|
155
|
+
}
|
|
156
|
+
return links;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parse the flat parameter set of `Common.LogActivity` into a `WriteManualActivityInput`.
|
|
160
|
+
*
|
|
161
|
+
* Conveniences for declarative bindings:
|
|
162
|
+
* - `EntityName` + `RecordID` (or `RecordData.ID`) become a leading `Regarding` link — the record
|
|
163
|
+
* the activity is about.
|
|
164
|
+
* - `LinkFields` routes the activity to records the subject points at (see the type's doc).
|
|
165
|
+
* - `EventKey` makes a binding idempotent per record: with `EntityName` and a record id present,
|
|
166
|
+
* `ExternalID` becomes `EntityName|RecordID|EventKey` and `SourceSystem` defaults to
|
|
167
|
+
* 'EntityAction', so a durable retry cannot double-log. Use it for one-per-record events
|
|
168
|
+
* (AfterCreate); leave it off when every firing should log (a status that changes repeatedly).
|
|
169
|
+
*/
|
|
170
|
+
export function ParseLogActivityParams(values) {
|
|
171
|
+
const reader = new ParamReader(values);
|
|
172
|
+
const typeCode = reader.string('TypeCode');
|
|
173
|
+
const title = reader.string('Title');
|
|
174
|
+
const startedAt = reader.date('StartedAt') ?? new Date();
|
|
175
|
+
const endedAt = reader.date('EndedAt');
|
|
176
|
+
const detailsValue = reader.object('Details');
|
|
177
|
+
if (detailsValue !== undefined && !isRecord(detailsValue)) {
|
|
178
|
+
reader.errors.push('Details must be a JSON object.');
|
|
179
|
+
}
|
|
180
|
+
const recordDataValue = reader.object('RecordData');
|
|
181
|
+
if (recordDataValue !== undefined && !isRecord(recordDataValue)) {
|
|
182
|
+
reader.errors.push('RecordData must be a JSON object (Entity Object Data).');
|
|
183
|
+
}
|
|
184
|
+
const recordData = isRecord(recordDataValue) ? recordDataValue : undefined;
|
|
185
|
+
const entityName = reader.string('EntityName');
|
|
186
|
+
const recordID = reader.string('RecordID') ?? (typeof recordData?.ID === 'string' ? recordData.ID : undefined);
|
|
187
|
+
const links = [];
|
|
188
|
+
if (entityName && recordID) {
|
|
189
|
+
links.push({ Role: 'Regarding', EntityName: entityName, RecordID: recordID });
|
|
190
|
+
}
|
|
191
|
+
else if ((entityName && !recordID) || (!entityName && recordID)) {
|
|
192
|
+
reader.errors.push('EntityName and RecordID (or RecordData.ID) must be provided together.');
|
|
193
|
+
}
|
|
194
|
+
links.push(...parseLinkFields(reader, recordData));
|
|
195
|
+
links.push(...parseLinkSpecs(reader));
|
|
196
|
+
let sourceSystem = reader.string('SourceSystem');
|
|
197
|
+
let externalID = reader.string('ExternalID');
|
|
198
|
+
const eventKey = reader.string('EventKey');
|
|
199
|
+
if (eventKey && !externalID) {
|
|
200
|
+
if (entityName && recordID) {
|
|
201
|
+
sourceSystem = sourceSystem ?? LOG_ACTIVITY_DEFAULT_SOURCE_SYSTEM;
|
|
202
|
+
externalID = `${entityName}|${recordID}|${eventKey}`;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
reader.errors.push('EventKey requires EntityName and a record id to derive an idempotency key.');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const input = {
|
|
209
|
+
TypeCode: typeCode ?? '',
|
|
210
|
+
Title: title ?? '',
|
|
211
|
+
StartedAt: startedAt,
|
|
212
|
+
EndedAt: endedAt ?? null,
|
|
213
|
+
Description: reader.string('Description') ?? null,
|
|
214
|
+
Direction: reader.oneOf('Direction', DIRECTIONS),
|
|
215
|
+
Status: reader.oneOf('Status', STATUSES),
|
|
216
|
+
Visibility: reader.oneOf('Visibility', VISIBILITIES),
|
|
217
|
+
Source: reader.oneOf('Source', SOURCES),
|
|
218
|
+
Location: reader.string('Location') ?? null,
|
|
219
|
+
Details: isRecord(detailsValue) ? detailsValue : null,
|
|
220
|
+
SourceSystem: sourceSystem ?? null,
|
|
221
|
+
ExternalID: externalID ?? null,
|
|
222
|
+
Links: links,
|
|
223
|
+
};
|
|
224
|
+
if (!typeCode)
|
|
225
|
+
reader.errors.push('TypeCode is required.');
|
|
226
|
+
if (!title)
|
|
227
|
+
reader.errors.push('Title is required.');
|
|
228
|
+
return reader.errors.length > 0 ? { Input: null, Errors: reader.errors } : { Input: input, Errors: [] };
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=manual-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-log.js","sourceRoot":"","sources":["../src/manual-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Internal vs external participants — the Outlook-rules control.
|
|
3
|
+
*
|
|
4
|
+
* "Internal" is not a property of a message. It is a property of the DEPLOYMENT, which is why the
|
|
5
|
+
* domain list lives on `ActivitySyncRuleSet.InternalDomains` and is passed in here rather than
|
|
6
|
+
* inferred. A rule that says "exclude internal-only chatter" is meaningless until someone has said
|
|
7
|
+
* which domains are ours.
|
|
8
|
+
*
|
|
9
|
+
* @module @mj-biz-apps/common-activity-sync
|
|
10
|
+
*/
|
|
11
|
+
import type { ItemParticipant } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Which participants must be present for a rule to apply.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors `CK_ActivitySyncRule_ParticipantScope`. `Mixed` exists because it is the case an
|
|
16
|
+
* all-or-nothing rule gets wrong: a thread with three colleagues and one customer on it is neither
|
|
17
|
+
* internal chatter nor an external conversation, and which of those it counts as is a decision a
|
|
18
|
+
* deployment should make explicitly.
|
|
19
|
+
*/
|
|
20
|
+
export type ParticipantScope = 'Any' | 'AllInternal' | 'AllExternal' | 'HasExternal' | 'HasInternal' | 'Mixed';
|
|
21
|
+
/** How a message's participants break down against the deployment's own domains. */
|
|
22
|
+
export interface ParticipantComposition {
|
|
23
|
+
Internal: number;
|
|
24
|
+
External: number;
|
|
25
|
+
/** Addresses with no parseable domain. Never counted as internal — see below. */
|
|
26
|
+
Unknown: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Split participants into internal and external by domain.
|
|
30
|
+
*
|
|
31
|
+
* **An unclassifiable address is never treated as internal.** A malformed or domain-less address is
|
|
32
|
+
* counted separately and, for every predicate below, sides with `External`. The alternative —
|
|
33
|
+
* assuming an unparseable party is one of us — would let a single bad address turn a mixed thread
|
|
34
|
+
* into "internal only", and an internal-only *exclusion* rule would then silently drop a real
|
|
35
|
+
* customer conversation. Erring the other way costs an extra captured message, which is recoverable;
|
|
36
|
+
* a silent drop is not.
|
|
37
|
+
*/
|
|
38
|
+
export declare function ClassifyParticipants(participants: readonly ItemParticipant[], internalDomains: readonly string[]): ParticipantComposition;
|
|
39
|
+
/** The domain part of an address, lower-cased, or null when there isn't one. */
|
|
40
|
+
export declare function DomainOf(address: string): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a composition satisfies a rule's required scope.
|
|
43
|
+
*
|
|
44
|
+
* `Unknown` sides with external throughout, per the reasoning on {@link ClassifyParticipants}.
|
|
45
|
+
*/
|
|
46
|
+
export declare function MatchesParticipantScope(scope: ParticipantScope, c: ParticipantComposition): boolean;
|
|
47
|
+
//# sourceMappingURL=participants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"participants.d.ts","sourceRoot":"","sources":["../src/participants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GACtB,KAAK,GACL,aAAa,GACb,aAAa,GACb,aAAa,GACb,aAAa,GACb,OAAO,CAAC;AAEd,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,YAAY,EAAE,SAAS,eAAe,EAAE,EACxC,eAAe,EAAE,SAAS,MAAM,EAAE,GACnC,sBAAsB,CAexB;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAgBnG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split participants into internal and external by domain.
|
|
3
|
+
*
|
|
4
|
+
* **An unclassifiable address is never treated as internal.** A malformed or domain-less address is
|
|
5
|
+
* counted separately and, for every predicate below, sides with `External`. The alternative —
|
|
6
|
+
* assuming an unparseable party is one of us — would let a single bad address turn a mixed thread
|
|
7
|
+
* into "internal only", and an internal-only *exclusion* rule would then silently drop a real
|
|
8
|
+
* customer conversation. Erring the other way costs an extra captured message, which is recoverable;
|
|
9
|
+
* a silent drop is not.
|
|
10
|
+
*/
|
|
11
|
+
export function ClassifyParticipants(participants, internalDomains) {
|
|
12
|
+
const domains = new Set(internalDomains.map((d) => d.trim().toLowerCase().replace(/^@/, '')));
|
|
13
|
+
const composition = { Internal: 0, External: 0, Unknown: 0 };
|
|
14
|
+
for (const participant of participants) {
|
|
15
|
+
const domain = DomainOf(participant.Address);
|
|
16
|
+
if (domain === null) {
|
|
17
|
+
composition.Unknown++;
|
|
18
|
+
}
|
|
19
|
+
else if (domains.has(domain)) {
|
|
20
|
+
composition.Internal++;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
composition.External++;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return composition;
|
|
27
|
+
}
|
|
28
|
+
/** The domain part of an address, lower-cased, or null when there isn't one. */
|
|
29
|
+
export function DomainOf(address) {
|
|
30
|
+
const at = address.lastIndexOf('@');
|
|
31
|
+
if (at < 0 || at === address.length - 1) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const domain = address.slice(at + 1).trim().toLowerCase();
|
|
35
|
+
return domain.length > 0 ? domain : null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Whether a composition satisfies a rule's required scope.
|
|
39
|
+
*
|
|
40
|
+
* `Unknown` sides with external throughout, per the reasoning on {@link ClassifyParticipants}.
|
|
41
|
+
*/
|
|
42
|
+
export function MatchesParticipantScope(scope, c) {
|
|
43
|
+
const external = c.External + c.Unknown;
|
|
44
|
+
switch (scope) {
|
|
45
|
+
case 'Any':
|
|
46
|
+
return true;
|
|
47
|
+
case 'AllInternal':
|
|
48
|
+
return c.Internal > 0 && external === 0;
|
|
49
|
+
case 'AllExternal':
|
|
50
|
+
return external > 0 && c.Internal === 0;
|
|
51
|
+
case 'HasExternal':
|
|
52
|
+
return external > 0;
|
|
53
|
+
case 'HasInternal':
|
|
54
|
+
return c.Internal > 0;
|
|
55
|
+
case 'Mixed':
|
|
56
|
+
return c.Internal > 0 && external > 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=participants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"participants.js","sourceRoot":"","sources":["../src/participants.ts"],"names":[],"mappings":"AAoCA;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAChC,YAAwC,EACxC,eAAkC;IAElC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,WAAW,GAA2B,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAErF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClB,WAAW,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC;aAAM,CAAC;YACJ,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IACD,OAAO,WAAW,CAAC;AACvB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,OAAe;IACpC,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAuB,EAAE,CAAyB;IACtF,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC;IACxC,QAAQ,KAAK,EAAE,CAAC;QACZ,KAAK,KAAK;YACN,OAAO,IAAI,CAAC;QAChB,KAAK,aAAa;YACd,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC;QAC5C,KAAK,aAAa;YACd,OAAO,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC;QAC5C,KAAK,aAAa;YACd,OAAO,QAAQ,GAAG,CAAC,CAAC;QACxB,KAAK,aAAa;YACd,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC1B,KAAK,OAAO;YACR,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;IAC9C,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseActivitySyncProvider } from '../BaseActivitySyncProvider.js';
|
|
2
|
+
import type { ActivitySourceKind, ActivitySourceQuery, NormalizedItem, RawBatch } from '../types.js';
|
|
3
|
+
export declare class FixtureActivitySyncProvider extends BaseActivitySyncProvider {
|
|
4
|
+
private readonly items;
|
|
5
|
+
private readonly issues;
|
|
6
|
+
readonly Kind: ActivitySourceKind;
|
|
7
|
+
readonly ProviderTypeCode = "Generic";
|
|
8
|
+
readonly IsLive = false;
|
|
9
|
+
readonly Calls: ActivitySourceQuery[];
|
|
10
|
+
fetchedAt: Date;
|
|
11
|
+
constructor(items?: NormalizedItem[], kind?: ActivitySourceKind, issues?: string[]);
|
|
12
|
+
/**
|
|
13
|
+
* The instant a CALENDAR fixture reports as its watermark. Injectable so a
|
|
14
|
+
* check can assert an exact value instead of racing the clock. Messages
|
|
15
|
+
* still use max(StartedAt) via Kind.
|
|
16
|
+
*/
|
|
17
|
+
protected Now(): Date;
|
|
18
|
+
protected FetchRaw(query: ActivitySourceQuery): Promise<RawBatch>;
|
|
19
|
+
protected Normalize(raw: RawBatch): NormalizedItem[];
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=FixtureActivitySyncProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixtureActivitySyncProvider.d.ts","sourceRoot":"","sources":["../../src/providers/FixtureActivitySyncProvider.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAErG,qBACa,2BAA4B,SAAQ,wBAAwB;IAQjE,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAT3B,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IACzC,SAAgB,gBAAgB,aAAa;IAC7C,SAAgB,MAAM,SAAS;IAC/B,SAAgB,KAAK,EAAE,mBAAmB,EAAE,CAAM;IAC3C,SAAS,EAAE,IAAI,CAAc;gBAGf,KAAK,GAAE,cAAc,EAAO,EAC7C,IAAI,GAAE,kBAA8B,EACnB,MAAM,GAAE,MAAM,EAAO;IAM1C;;;;OAIG;cACgB,GAAG,IAAI,IAAI;cAId,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAavE,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,cAAc,EAAE;CAGvD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A source backed by handed-in items. The substitute the pipeline is proved against.
|
|
12
|
+
*
|
|
13
|
+
* Not a mock: it hands over the same NormalizedItem[] a live provider would, so a test
|
|
14
|
+
* exercises the real cascade, resolver, writer and watermark.
|
|
15
|
+
*/
|
|
16
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
17
|
+
import { BaseActivitySyncProvider } from '../BaseActivitySyncProvider.js';
|
|
18
|
+
let FixtureActivitySyncProvider = class FixtureActivitySyncProvider extends BaseActivitySyncProvider {
|
|
19
|
+
constructor(items = [], kind = 'Message', issues = []) {
|
|
20
|
+
super();
|
|
21
|
+
this.items = items;
|
|
22
|
+
this.issues = issues;
|
|
23
|
+
this.ProviderTypeCode = 'Generic';
|
|
24
|
+
this.IsLive = false;
|
|
25
|
+
this.Calls = [];
|
|
26
|
+
this.fetchedAt = new Date();
|
|
27
|
+
this.Kind = kind;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The instant a CALENDAR fixture reports as its watermark. Injectable so a
|
|
31
|
+
* check can assert an exact value instead of racing the clock. Messages
|
|
32
|
+
* still use max(StartedAt) via Kind.
|
|
33
|
+
*/
|
|
34
|
+
Now() {
|
|
35
|
+
return this.fetchedAt;
|
|
36
|
+
}
|
|
37
|
+
async FetchRaw(query) {
|
|
38
|
+
this.Calls.push(query);
|
|
39
|
+
const since = query.Since ? query.Since.getTime() : null;
|
|
40
|
+
const eligible = this.items
|
|
41
|
+
.filter((item) => since === null || item.StartedAt.getTime() > since)
|
|
42
|
+
.sort((a, b) => a.StartedAt.getTime() - b.StartedAt.getTime())
|
|
43
|
+
.slice(0, Math.max(0, query.Limit));
|
|
44
|
+
return {
|
|
45
|
+
Payloads: eligible.map((item) => ({ item })),
|
|
46
|
+
Issues: [...this.issues],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
Normalize(raw) {
|
|
50
|
+
return raw.Payloads.map((p) => p.item);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
FixtureActivitySyncProvider = __decorate([
|
|
54
|
+
RegisterClass(BaseActivitySyncProvider, 'Generic'),
|
|
55
|
+
__metadata("design:paramtypes", [Array, String, Array])
|
|
56
|
+
], FixtureActivitySyncProvider);
|
|
57
|
+
export { FixtureActivitySyncProvider };
|
|
58
|
+
//# sourceMappingURL=FixtureActivitySyncProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixtureActivitySyncProvider.js","sourceRoot":"","sources":["../../src/providers/FixtureActivitySyncProvider.ts"],"names":[],"mappings":";;;;;;;;;AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAInE,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,wBAAwB;IAOrE,YACqB,QAA0B,EAAE,EAC7C,OAA2B,SAAS,EACnB,SAAmB,EAAE;QAEtC,KAAK,EAAE,CAAC;QAJS,UAAK,GAAL,KAAK,CAAuB;QAE5B,WAAM,GAAN,MAAM,CAAe;QAR1B,qBAAgB,GAAG,SAAS,CAAC;QAC7B,WAAM,GAAG,KAAK,CAAC;QACf,UAAK,GAA0B,EAAE,CAAC;QAC3C,cAAS,GAAS,IAAI,IAAI,EAAE,CAAC;QAQhC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACgB,GAAG;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAES,KAAK,CAAC,QAAQ,CAAC,KAA0B;QAC/C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK;aACtB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC;aACpE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;aAC7D,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,OAAO;YACH,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;SAC3B,CAAC;IACN,CAAC;IAES,SAAS,CAAC,GAAa;QAC7B,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAsB,CAAC,CAAC;IAC7D,CAAC;CACJ,CAAA;AAzCY,2BAA2B;IADvC,aAAa,CAAC,wBAAwB,EAAE,SAAS,CAAC;;GACtC,2BAA2B,CAyCvC"}
|