@memberjunction/connector-fonteva 1.0.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/FontevaConnector.d.ts +152 -0
- package/dist/FontevaConnector.js +421 -0
- package/dist/FontevaConnector.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { UserInfo } from '@memberjunction/core';
|
|
2
|
+
import type { MJCompanyIntegrationEntity } from '@memberjunction/core-entities';
|
|
3
|
+
import { type ExternalObjectSchema, type ExternalFieldSchema, type FetchContext, type FetchBatchResult, type ExternalRecord, type CRUDResult, type CreateRecordContext, type UpdateRecordContext, type DeleteRecordContext, type GetRecordContext, type SearchContext, type SearchResult, type SourceSchemaInfo, type IntrospectSchemaOptions } from '@memberjunction/integration-engine';
|
|
4
|
+
import { SalesforceConnector } from '@memberjunction/connector-salesforce';
|
|
5
|
+
/**
|
|
6
|
+
* Fonteva AMS connector.
|
|
7
|
+
*
|
|
8
|
+
* Fonteva is a Salesforce **managed package** (the OrderApi__ and EventApi__
|
|
9
|
+
* namespaces), so it rides the core Salesforce REST infrastructure verbatim.
|
|
10
|
+
* This connector therefore COMPOSES on {@link SalesforceConnector}, reusing —
|
|
11
|
+
* unchanged — its:
|
|
12
|
+
* - Salesforce OAuth2 bearer authentication (JWT-bearer / client-credentials),
|
|
13
|
+
* - global describe object discovery (`/services/data/vXX/sobjects/`),
|
|
14
|
+
* - per-object `/describe` field discovery,
|
|
15
|
+
* - SOQL incremental fetch with `nextRecordsUrl` cursor pagination,
|
|
16
|
+
* - `SystemModstamp` watermark incremental sync,
|
|
17
|
+
* - generic sObject CRUD (POST/PATCH/DELETE) and the `BuildCreatedResult`
|
|
18
|
+
* loud-fail-on-empty-ID write contract.
|
|
19
|
+
*
|
|
20
|
+
* The Fonteva-specific layer added here is intentionally thin:
|
|
21
|
+
* 1. **Namespace scoping** — `DiscoverObjects` filters the inherited Salesforce
|
|
22
|
+
* global describe down to the managed-package namespaces (OrderApi__ /
|
|
23
|
+
* EventApi__), so the connector surfaces ONLY Fonteva AMS objects (the
|
|
24
|
+
* standard SF CRM objects are the SalesforceConnector's job).
|
|
25
|
+
* 2. **IO-name ↔ backing-sObject translation** — the friendly IO `Name`
|
|
26
|
+
* ("Assignment") is mapped to its real sObject API name
|
|
27
|
+
* ("OrderApi__Assignment__c", read from the IO's Configuration) before
|
|
28
|
+
* every inherited Salesforce operation, and the returned records'
|
|
29
|
+
* `ObjectType` is rewritten back to the IO name for engine identity.
|
|
30
|
+
* 3. **FDService domain services** — the `/services/apexrest/FDService/*` Apex
|
|
31
|
+
* REST services are wired as an opt-in read path with the documented
|
|
32
|
+
* SearchRequest filter/fields/sort/limit query params.
|
|
33
|
+
*
|
|
34
|
+
* Discovery is the live global-describe MECHANISM (no baked catalog); the object
|
|
35
|
+
* universe is Declared (docs) + Discovered (runtime describe). Writes use the
|
|
36
|
+
* inherited generic sObject CRUD; FDService write shapes are not idiosyncratic
|
|
37
|
+
* enough to warrant overriding the sObject write path (the metadata routes all
|
|
38
|
+
* writes through the platform sObject endpoints).
|
|
39
|
+
*/
|
|
40
|
+
export declare class FontevaConnector extends SalesforceConnector {
|
|
41
|
+
private _fontevaConfig;
|
|
42
|
+
get IntegrationName(): string;
|
|
43
|
+
/**
|
|
44
|
+
* AUTHORITATIVE discovery (inherited rationale): the scoped global describe
|
|
45
|
+
* enumerates the COMPLETE set of Fonteva managed-package objects the
|
|
46
|
+
* credentials expose, so absence in a refresh genuinely means the object was
|
|
47
|
+
* removed and the engine may safely deactivate it. Kept explicit so the
|
|
48
|
+
* Fonteva-scoped filter doesn't quietly inherit a non-authoritative default.
|
|
49
|
+
*/
|
|
50
|
+
get DiscoveryIsAuthoritative(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Parses the integration-level Configuration JSON for the Fonteva-specific
|
|
53
|
+
* knobs (managed-package namespaces, FDService base path, opt-in FDService
|
|
54
|
+
* read). Tolerant of missing/invalid Configuration — falls back to documented
|
|
55
|
+
* defaults so a freshly-seeded integration works without extra config.
|
|
56
|
+
*/
|
|
57
|
+
private GetFontevaConfig;
|
|
58
|
+
/**
|
|
59
|
+
* Discovers Fonteva objects by reusing the inherited Salesforce global
|
|
60
|
+
* describe and filtering it to the managed-package namespaces. NO baked
|
|
61
|
+
* catalog — the list comes entirely from the live `/sobjects/` describe; this
|
|
62
|
+
* method only scopes it and presents the friendly (namespace-stripped) IO name.
|
|
63
|
+
*/
|
|
64
|
+
DiscoverObjects(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Builds a reverse map (lower-cased backing sObject API name → declared IO Name) from the
|
|
67
|
+
* loaded metadata — the inverse of {@link ResolveBackingSObject}. Used at discovery time so a
|
|
68
|
+
* discovered sObject resolves to the IO the metadata actually declares for it, instead of a
|
|
69
|
+
* mechanically-derived name that may not round-trip (singular/plural, wrapper-vs-sObject renames).
|
|
70
|
+
* Returns an empty map when the engine cache isn't populated (e.g. unit tests) — callers then
|
|
71
|
+
* fall back to {@link SObjectToFriendlyName}.
|
|
72
|
+
*/
|
|
73
|
+
private BuildBackingSObjectReverseMap;
|
|
74
|
+
/**
|
|
75
|
+
* Discovers fields for a Fonteva object. Translates the friendly IO name back
|
|
76
|
+
* to its backing sObject API name, then reuses the inherited Salesforce
|
|
77
|
+
* `/describe` field discovery verbatim.
|
|
78
|
+
*/
|
|
79
|
+
DiscoverFields(companyIntegration: MJCompanyIntegrationEntity, objectName: string, contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Full schema introspection scoped to the managed-package namespaces. Defers
|
|
82
|
+
* entirely to the inherited Salesforce introspection (which calls
|
|
83
|
+
* DiscoverObjects — overridden here to scope — then `/describe`s each), but
|
|
84
|
+
* re-resolves any caller-supplied ObjectNames (friendly IO names) to their
|
|
85
|
+
* backing sObjects so the inherited describe loop targets real sObjects.
|
|
86
|
+
*/
|
|
87
|
+
IntrospectSchema(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo, options?: IntrospectSchemaOptions): Promise<SourceSchemaInfo>;
|
|
88
|
+
/**
|
|
89
|
+
* Fetches changed records. Default path reuses the inherited Salesforce SOQL
|
|
90
|
+
* incremental fetch (SystemModstamp watermark + nextRecordsUrl cursor)
|
|
91
|
+
* verbatim, with the IO name translated to its backing sObject. When the
|
|
92
|
+
* connection opts into FDService reads (`UseFDServiceForRead`), routes through
|
|
93
|
+
* the FDService Apex REST domain service instead.
|
|
94
|
+
*/
|
|
95
|
+
FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
|
|
96
|
+
CreateRecord(ctx: CreateRecordContext): Promise<CRUDResult>;
|
|
97
|
+
UpdateRecord(ctx: UpdateRecordContext): Promise<CRUDResult>;
|
|
98
|
+
DeleteRecord(ctx: DeleteRecordContext): Promise<CRUDResult>;
|
|
99
|
+
GetRecord(ctx: GetRecordContext): Promise<ExternalRecord | null>;
|
|
100
|
+
SearchRecords(ctx: SearchContext): Promise<SearchResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Reads records through a Fonteva FDService Apex REST domain service using
|
|
103
|
+
* the documented SearchRequest parameters (filter / fields / sort / limit).
|
|
104
|
+
* The connector follows the SystemModstamp watermark by encoding a SOQL WHERE
|
|
105
|
+
* fragment into the `filter` (a.k.a. whereClause) param.
|
|
106
|
+
*
|
|
107
|
+
* Idiosyncratic to Fonteva: FDService returns the wrapper records under a
|
|
108
|
+
* `records` key (camelCase wrapper properties), with the universal `id`
|
|
109
|
+
* property carrying the Salesforce 18-char Id. There is no documented cursor
|
|
110
|
+
* token, so pagination is bounded by `limit` and advanced by the watermark on
|
|
111
|
+
* subsequent syncs (the connector reports the max SystemModstamp it saw).
|
|
112
|
+
*/
|
|
113
|
+
private FetchViaFDService;
|
|
114
|
+
/** Builds SearchRequest params from the fetch context (watermark → filter). */
|
|
115
|
+
private BuildFDServiceSearchParams;
|
|
116
|
+
private EncodeFDServiceParams;
|
|
117
|
+
private FormatFDServiceDateTime;
|
|
118
|
+
/**
|
|
119
|
+
* Parses an FDService response into ExternalRecords. FDService wraps records
|
|
120
|
+
* under a `records` array (each a flat camelCase wrapper object whose `id`
|
|
121
|
+
* carries the Salesforce Id). Preserves the FULL record into Fields for
|
|
122
|
+
* custom-column capture — no narrow projection.
|
|
123
|
+
*/
|
|
124
|
+
private ParseFDServiceRecords;
|
|
125
|
+
private MaxSystemModstamp;
|
|
126
|
+
private BuildFDServicePath;
|
|
127
|
+
/**
|
|
128
|
+
* Resolves the friendly IO `Name` to its backing Salesforce sObject API name.
|
|
129
|
+
* Reads the IO's Configuration.BackingSObject from the engine cache; falls
|
|
130
|
+
* back to a namespace-prefixed PascalSnake derivation when metadata isn't
|
|
131
|
+
* loaded (e.g. unit tests) or the IO already IS a fully-qualified sObject.
|
|
132
|
+
*/
|
|
133
|
+
private ResolveBackingSObject;
|
|
134
|
+
/** Reads + parses the per-IO Configuration from the engine cache. Returns null if unavailable. */
|
|
135
|
+
private GetObjectConfig;
|
|
136
|
+
private IsInManagedPackage;
|
|
137
|
+
/**
|
|
138
|
+
* Presents a managed-package sObject API name as a friendly IO name by
|
|
139
|
+
* stripping the namespace prefix and the `__c` suffix and PascalCasing the
|
|
140
|
+
* snake segments (e.g. OrderApi__Sales_Order_Line__c → SalesOrderLine).
|
|
141
|
+
*/
|
|
142
|
+
private SObjectToFriendlyName;
|
|
143
|
+
/** Rewrites a fetch batch's record ObjectType from the backing sObject back to the IO name. */
|
|
144
|
+
private RewriteObjectType;
|
|
145
|
+
private AuthenticateForFonteva;
|
|
146
|
+
private FontevaHeaders;
|
|
147
|
+
private MakeFontevaRequest;
|
|
148
|
+
private FontevaApiBase;
|
|
149
|
+
private PreviewFonteva;
|
|
150
|
+
}
|
|
151
|
+
/** Tree-shaking prevention: referenced from index.ts so the @RegisterClass survives bundling. */
|
|
152
|
+
export declare function LoadFontevaConnector(): void;
|
|
@@ -0,0 +1,421 @@
|
|
|
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
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { IntegrationEngineBase } from '@memberjunction/integration-engine-base';
|
|
9
|
+
import { BaseIntegrationConnector, } from '@memberjunction/integration-engine';
|
|
10
|
+
import { SalesforceConnector } from '@memberjunction/connector-salesforce';
|
|
11
|
+
// ─── Constants ────────────────────────────────────────────────────────
|
|
12
|
+
const DEFAULT_MANAGED_PACKAGE_NAMESPACES = ['orderapi', 'eventapi'];
|
|
13
|
+
const DEFAULT_FDSERVICE_BASE_PATH = '/services/apexrest/FDService';
|
|
14
|
+
// ─── FontevaConnector ──────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Fonteva AMS connector.
|
|
17
|
+
*
|
|
18
|
+
* Fonteva is a Salesforce **managed package** (the OrderApi__ and EventApi__
|
|
19
|
+
* namespaces), so it rides the core Salesforce REST infrastructure verbatim.
|
|
20
|
+
* This connector therefore COMPOSES on {@link SalesforceConnector}, reusing —
|
|
21
|
+
* unchanged — its:
|
|
22
|
+
* - Salesforce OAuth2 bearer authentication (JWT-bearer / client-credentials),
|
|
23
|
+
* - global describe object discovery (`/services/data/vXX/sobjects/`),
|
|
24
|
+
* - per-object `/describe` field discovery,
|
|
25
|
+
* - SOQL incremental fetch with `nextRecordsUrl` cursor pagination,
|
|
26
|
+
* - `SystemModstamp` watermark incremental sync,
|
|
27
|
+
* - generic sObject CRUD (POST/PATCH/DELETE) and the `BuildCreatedResult`
|
|
28
|
+
* loud-fail-on-empty-ID write contract.
|
|
29
|
+
*
|
|
30
|
+
* The Fonteva-specific layer added here is intentionally thin:
|
|
31
|
+
* 1. **Namespace scoping** — `DiscoverObjects` filters the inherited Salesforce
|
|
32
|
+
* global describe down to the managed-package namespaces (OrderApi__ /
|
|
33
|
+
* EventApi__), so the connector surfaces ONLY Fonteva AMS objects (the
|
|
34
|
+
* standard SF CRM objects are the SalesforceConnector's job).
|
|
35
|
+
* 2. **IO-name ↔ backing-sObject translation** — the friendly IO `Name`
|
|
36
|
+
* ("Assignment") is mapped to its real sObject API name
|
|
37
|
+
* ("OrderApi__Assignment__c", read from the IO's Configuration) before
|
|
38
|
+
* every inherited Salesforce operation, and the returned records'
|
|
39
|
+
* `ObjectType` is rewritten back to the IO name for engine identity.
|
|
40
|
+
* 3. **FDService domain services** — the `/services/apexrest/FDService/*` Apex
|
|
41
|
+
* REST services are wired as an opt-in read path with the documented
|
|
42
|
+
* SearchRequest filter/fields/sort/limit query params.
|
|
43
|
+
*
|
|
44
|
+
* Discovery is the live global-describe MECHANISM (no baked catalog); the object
|
|
45
|
+
* universe is Declared (docs) + Discovered (runtime describe). Writes use the
|
|
46
|
+
* inherited generic sObject CRUD; FDService write shapes are not idiosyncratic
|
|
47
|
+
* enough to warrant overriding the sObject write path (the metadata routes all
|
|
48
|
+
* writes through the platform sObject endpoints).
|
|
49
|
+
*/
|
|
50
|
+
let FontevaConnector = class FontevaConnector extends SalesforceConnector {
|
|
51
|
+
constructor() {
|
|
52
|
+
super(...arguments);
|
|
53
|
+
this._fontevaConfig = null;
|
|
54
|
+
}
|
|
55
|
+
// ─── Identity (three-way invariant) ──────────────────────────────
|
|
56
|
+
get IntegrationName() { return 'Fonteva'; }
|
|
57
|
+
/**
|
|
58
|
+
* AUTHORITATIVE discovery (inherited rationale): the scoped global describe
|
|
59
|
+
* enumerates the COMPLETE set of Fonteva managed-package objects the
|
|
60
|
+
* credentials expose, so absence in a refresh genuinely means the object was
|
|
61
|
+
* removed and the engine may safely deactivate it. Kept explicit so the
|
|
62
|
+
* Fonteva-scoped filter doesn't quietly inherit a non-authoritative default.
|
|
63
|
+
*/
|
|
64
|
+
get DiscoveryIsAuthoritative() { return true; }
|
|
65
|
+
// ─── Config ──────────────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Parses the integration-level Configuration JSON for the Fonteva-specific
|
|
68
|
+
* knobs (managed-package namespaces, FDService base path, opt-in FDService
|
|
69
|
+
* read). Tolerant of missing/invalid Configuration — falls back to documented
|
|
70
|
+
* defaults so a freshly-seeded integration works without extra config.
|
|
71
|
+
*/
|
|
72
|
+
GetFontevaConfig(companyIntegration) {
|
|
73
|
+
if (this._fontevaConfig)
|
|
74
|
+
return this._fontevaConfig;
|
|
75
|
+
const defaults = {
|
|
76
|
+
ManagedPackageNamespaces: [...DEFAULT_MANAGED_PACKAGE_NAMESPACES],
|
|
77
|
+
FDServiceBasePath: DEFAULT_FDSERVICE_BASE_PATH,
|
|
78
|
+
UseFDServiceForRead: false,
|
|
79
|
+
};
|
|
80
|
+
const raw = companyIntegration.Configuration;
|
|
81
|
+
if (!raw) {
|
|
82
|
+
this._fontevaConfig = defaults;
|
|
83
|
+
return defaults;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(raw);
|
|
87
|
+
const namespaces = Array.isArray(parsed['ManagedPackageNamespaces'])
|
|
88
|
+
? parsed['ManagedPackageNamespaces']
|
|
89
|
+
.filter((n) => typeof n === 'string')
|
|
90
|
+
.map(n => n.toLowerCase())
|
|
91
|
+
: defaults.ManagedPackageNamespaces;
|
|
92
|
+
const fdBasePath = typeof parsed['FDServiceBasePath'] === 'string'
|
|
93
|
+
? parsed['FDServiceBasePath']
|
|
94
|
+
: defaults.FDServiceBasePath;
|
|
95
|
+
const useFDService = parsed['UseFDServiceForRead'] === true;
|
|
96
|
+
this._fontevaConfig = {
|
|
97
|
+
ManagedPackageNamespaces: namespaces.length > 0 ? namespaces : defaults.ManagedPackageNamespaces,
|
|
98
|
+
FDServiceBasePath: fdBasePath,
|
|
99
|
+
UseFDServiceForRead: useFDService,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
this._fontevaConfig = defaults;
|
|
104
|
+
}
|
|
105
|
+
return this._fontevaConfig;
|
|
106
|
+
}
|
|
107
|
+
// ─── Discovery (scoped to the managed-package namespaces) ────────
|
|
108
|
+
/**
|
|
109
|
+
* Discovers Fonteva objects by reusing the inherited Salesforce global
|
|
110
|
+
* describe and filtering it to the managed-package namespaces. NO baked
|
|
111
|
+
* catalog — the list comes entirely from the live `/sobjects/` describe; this
|
|
112
|
+
* method only scopes it and presents the friendly (namespace-stripped) IO name.
|
|
113
|
+
*/
|
|
114
|
+
async DiscoverObjects(companyIntegration, contextUser) {
|
|
115
|
+
const cfg = this.GetFontevaConfig(companyIntegration);
|
|
116
|
+
const all = await super.DiscoverObjects(companyIntegration, contextUser);
|
|
117
|
+
const sObjectToIOName = this.BuildBackingSObjectReverseMap(companyIntegration);
|
|
118
|
+
return all
|
|
119
|
+
.filter(o => this.IsInManagedPackage(o.Name, cfg.ManagedPackageNamespaces))
|
|
120
|
+
.map(o => ({
|
|
121
|
+
...o,
|
|
122
|
+
// Prefer the DECLARED IO name whose Configuration.BackingSObject matches this sObject —
|
|
123
|
+
// this lets IOs whose name diverges from the mechanical derivation map correctly
|
|
124
|
+
// (Term → OrderApi__Renewal__c, EventChatterGroup → EventApi__Event_Chatter_Groups__c).
|
|
125
|
+
// Fall back to the mechanical namespace-strip + PascalCase when no declared mapping exists
|
|
126
|
+
// (a genuinely Discovered object the metadata doesn't yet name).
|
|
127
|
+
Name: sObjectToIOName.get(o.Name.toLowerCase()) ?? this.SObjectToFriendlyName(o.Name),
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Builds a reverse map (lower-cased backing sObject API name → declared IO Name) from the
|
|
132
|
+
* loaded metadata — the inverse of {@link ResolveBackingSObject}. Used at discovery time so a
|
|
133
|
+
* discovered sObject resolves to the IO the metadata actually declares for it, instead of a
|
|
134
|
+
* mechanically-derived name that may not round-trip (singular/plural, wrapper-vs-sObject renames).
|
|
135
|
+
* Returns an empty map when the engine cache isn't populated (e.g. unit tests) — callers then
|
|
136
|
+
* fall back to {@link SObjectToFriendlyName}.
|
|
137
|
+
*/
|
|
138
|
+
BuildBackingSObjectReverseMap(companyIntegration) {
|
|
139
|
+
const map = new Map();
|
|
140
|
+
try {
|
|
141
|
+
const ios = IntegrationEngineBase.Instance.IntegrationObjects.filter(io => io.IntegrationID === companyIntegration.IntegrationID);
|
|
142
|
+
for (const io of ios) {
|
|
143
|
+
if (!io.Configuration)
|
|
144
|
+
continue;
|
|
145
|
+
try {
|
|
146
|
+
const objCfg = JSON.parse(io.Configuration);
|
|
147
|
+
if (objCfg.BackingSObject)
|
|
148
|
+
map.set(objCfg.BackingSObject.toLowerCase(), io.Name);
|
|
149
|
+
}
|
|
150
|
+
catch { /* unparseable Configuration — skip this IO */ }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch { /* engine cache unavailable — caller falls back to mechanical derivation */ }
|
|
154
|
+
return map;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Discovers fields for a Fonteva object. Translates the friendly IO name back
|
|
158
|
+
* to its backing sObject API name, then reuses the inherited Salesforce
|
|
159
|
+
* `/describe` field discovery verbatim.
|
|
160
|
+
*/
|
|
161
|
+
async DiscoverFields(companyIntegration, objectName, contextUser) {
|
|
162
|
+
const sObject = this.ResolveBackingSObject(companyIntegration, objectName);
|
|
163
|
+
return super.DiscoverFields(companyIntegration, sObject, contextUser);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Full schema introspection scoped to the managed-package namespaces. Defers
|
|
167
|
+
* entirely to the inherited Salesforce introspection (which calls
|
|
168
|
+
* DiscoverObjects — overridden here to scope — then `/describe`s each), but
|
|
169
|
+
* re-resolves any caller-supplied ObjectNames (friendly IO names) to their
|
|
170
|
+
* backing sObjects so the inherited describe loop targets real sObjects.
|
|
171
|
+
*/
|
|
172
|
+
async IntrospectSchema(companyIntegration, contextUser, options) {
|
|
173
|
+
if (options?.ObjectNames && options.ObjectNames.length > 0) {
|
|
174
|
+
const resolved = options.ObjectNames.map(n => this.ResolveBackingSObject(companyIntegration, n));
|
|
175
|
+
return super.IntrospectSchema(companyIntegration, contextUser, { ...options, ObjectNames: resolved });
|
|
176
|
+
}
|
|
177
|
+
return super.IntrospectSchema(companyIntegration, contextUser, options);
|
|
178
|
+
}
|
|
179
|
+
// ─── Fetch (SOQL platform layer reused; FDService opt-in) ────────
|
|
180
|
+
/**
|
|
181
|
+
* Fetches changed records. Default path reuses the inherited Salesforce SOQL
|
|
182
|
+
* incremental fetch (SystemModstamp watermark + nextRecordsUrl cursor)
|
|
183
|
+
* verbatim, with the IO name translated to its backing sObject. When the
|
|
184
|
+
* connection opts into FDService reads (`UseFDServiceForRead`), routes through
|
|
185
|
+
* the FDService Apex REST domain service instead.
|
|
186
|
+
*/
|
|
187
|
+
async FetchChanges(ctx) {
|
|
188
|
+
const cfg = this.GetFontevaConfig(ctx.CompanyIntegration);
|
|
189
|
+
const ioName = ctx.ObjectName;
|
|
190
|
+
const objCfg = this.GetObjectConfig(ctx.CompanyIntegration, ioName);
|
|
191
|
+
if (cfg.UseFDServiceForRead && objCfg?.AccessPath?.fdServicePath) {
|
|
192
|
+
const batch = await this.FetchViaFDService(ctx, objCfg, cfg);
|
|
193
|
+
return this.RewriteObjectType(batch, ioName);
|
|
194
|
+
}
|
|
195
|
+
const sObject = objCfg?.BackingSObject ?? this.ResolveBackingSObject(ctx.CompanyIntegration, ioName);
|
|
196
|
+
const batch = await super.FetchChanges({ ...ctx, ObjectName: sObject });
|
|
197
|
+
return this.RewriteObjectType(batch, ioName);
|
|
198
|
+
}
|
|
199
|
+
// ─── CRUD (generic sObject path reused; IO name → sObject) ───────
|
|
200
|
+
async CreateRecord(ctx) {
|
|
201
|
+
const sObject = this.ResolveBackingSObject(ctx.CompanyIntegration, ctx.ObjectName);
|
|
202
|
+
return super.CreateRecord({ ...ctx, ObjectName: sObject });
|
|
203
|
+
}
|
|
204
|
+
async UpdateRecord(ctx) {
|
|
205
|
+
const sObject = this.ResolveBackingSObject(ctx.CompanyIntegration, ctx.ObjectName);
|
|
206
|
+
return super.UpdateRecord({ ...ctx, ObjectName: sObject });
|
|
207
|
+
}
|
|
208
|
+
async DeleteRecord(ctx) {
|
|
209
|
+
const sObject = this.ResolveBackingSObject(ctx.CompanyIntegration, ctx.ObjectName);
|
|
210
|
+
return super.DeleteRecord({ ...ctx, ObjectName: sObject });
|
|
211
|
+
}
|
|
212
|
+
async GetRecord(ctx) {
|
|
213
|
+
const sObject = this.ResolveBackingSObject(ctx.CompanyIntegration, ctx.ObjectName);
|
|
214
|
+
const record = await super.GetRecord({ ...ctx, ObjectName: sObject });
|
|
215
|
+
if (record)
|
|
216
|
+
record.ObjectType = ctx.ObjectName;
|
|
217
|
+
return record;
|
|
218
|
+
}
|
|
219
|
+
async SearchRecords(ctx) {
|
|
220
|
+
const sObject = this.ResolveBackingSObject(ctx.CompanyIntegration, ctx.ObjectName);
|
|
221
|
+
const result = await super.SearchRecords({ ...ctx, ObjectName: sObject });
|
|
222
|
+
for (const r of result.Records)
|
|
223
|
+
r.ObjectType = ctx.ObjectName;
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
// ─── FDService Apex REST domain services ─────────────────────────
|
|
227
|
+
/**
|
|
228
|
+
* Reads records through a Fonteva FDService Apex REST domain service using
|
|
229
|
+
* the documented SearchRequest parameters (filter / fields / sort / limit).
|
|
230
|
+
* The connector follows the SystemModstamp watermark by encoding a SOQL WHERE
|
|
231
|
+
* fragment into the `filter` (a.k.a. whereClause) param.
|
|
232
|
+
*
|
|
233
|
+
* Idiosyncratic to Fonteva: FDService returns the wrapper records under a
|
|
234
|
+
* `records` key (camelCase wrapper properties), with the universal `id`
|
|
235
|
+
* property carrying the Salesforce 18-char Id. There is no documented cursor
|
|
236
|
+
* token, so pagination is bounded by `limit` and advanced by the watermark on
|
|
237
|
+
* subsequent syncs (the connector reports the max SystemModstamp it saw).
|
|
238
|
+
*/
|
|
239
|
+
async FetchViaFDService(ctx, objCfg, cfg) {
|
|
240
|
+
const auth = await this.AuthenticateForFonteva(ctx.CompanyIntegration, ctx.ContextUser);
|
|
241
|
+
const servicePath = objCfg.AccessPath?.fdServicePath ?? this.BuildFDServicePath(cfg, objCfg);
|
|
242
|
+
const params = this.BuildFDServiceSearchParams(ctx);
|
|
243
|
+
const query = this.EncodeFDServiceParams(params);
|
|
244
|
+
const url = `${this.FontevaApiBase(auth)}${servicePath}${query ? `?${query}` : ''}`;
|
|
245
|
+
const headers = this.FontevaHeaders(auth);
|
|
246
|
+
const response = await this.MakeFontevaRequest(auth, url, 'GET', headers);
|
|
247
|
+
if (response.Status < 200 || response.Status >= 300) {
|
|
248
|
+
throw new Error(`Fonteva FDService GET ${url} returned HTTP ${response.Status}: ${this.PreviewFonteva(response.Body)}`);
|
|
249
|
+
}
|
|
250
|
+
const records = this.ParseFDServiceRecords(response.Body, ctx.ObjectName);
|
|
251
|
+
const newWatermark = this.MaxSystemModstamp(records);
|
|
252
|
+
return {
|
|
253
|
+
Records: records,
|
|
254
|
+
HasMore: false,
|
|
255
|
+
NewWatermarkValue: newWatermark ?? undefined,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/** Builds SearchRequest params from the fetch context (watermark → filter). */
|
|
259
|
+
BuildFDServiceSearchParams(ctx) {
|
|
260
|
+
const params = {
|
|
261
|
+
limit: ctx.BatchSize > 0 ? ctx.BatchSize : undefined,
|
|
262
|
+
sort: 'SystemModstamp',
|
|
263
|
+
sorDir: 'ASC',
|
|
264
|
+
};
|
|
265
|
+
if (ctx.WatermarkValue) {
|
|
266
|
+
params.filter = `SystemModstamp >= ${this.FormatFDServiceDateTime(ctx.WatermarkValue)}`;
|
|
267
|
+
}
|
|
268
|
+
if (ctx.RequestedSourceFields && ctx.RequestedSourceFields.length > 0) {
|
|
269
|
+
params.fields = ctx.RequestedSourceFields.join(',');
|
|
270
|
+
}
|
|
271
|
+
return params;
|
|
272
|
+
}
|
|
273
|
+
EncodeFDServiceParams(params) {
|
|
274
|
+
const usp = new URLSearchParams();
|
|
275
|
+
if (params.id)
|
|
276
|
+
usp.set('id', params.id);
|
|
277
|
+
if (params.filter)
|
|
278
|
+
usp.set('filter', params.filter);
|
|
279
|
+
if (params.fields)
|
|
280
|
+
usp.set('fields', params.fields);
|
|
281
|
+
if (params.sort)
|
|
282
|
+
usp.set('sort', params.sort);
|
|
283
|
+
if (params.sorDir)
|
|
284
|
+
usp.set('sorDir', params.sorDir);
|
|
285
|
+
if (params.limit != null)
|
|
286
|
+
usp.set('limit', String(params.limit));
|
|
287
|
+
return usp.toString();
|
|
288
|
+
}
|
|
289
|
+
FormatFDServiceDateTime(value) {
|
|
290
|
+
return value.includes('T') ? value : `${value}T00:00:00.000Z`;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Parses an FDService response into ExternalRecords. FDService wraps records
|
|
294
|
+
* under a `records` array (each a flat camelCase wrapper object whose `id`
|
|
295
|
+
* carries the Salesforce Id). Preserves the FULL record into Fields for
|
|
296
|
+
* custom-column capture — no narrow projection.
|
|
297
|
+
*/
|
|
298
|
+
ParseFDServiceRecords(body, objectType) {
|
|
299
|
+
const envelope = body;
|
|
300
|
+
const list = Array.isArray(envelope)
|
|
301
|
+
? envelope
|
|
302
|
+
: Array.isArray(envelope?.records) ? envelope.records : [];
|
|
303
|
+
return list.map(item => {
|
|
304
|
+
const raw = item;
|
|
305
|
+
const id = String(raw['id'] ?? raw['Id'] ?? '');
|
|
306
|
+
const modstamp = (raw['SystemModstamp'] ?? raw['systemModstamp']);
|
|
307
|
+
return {
|
|
308
|
+
ExternalID: id,
|
|
309
|
+
ObjectType: objectType,
|
|
310
|
+
Fields: { ...raw }, // full record pass-through (custom-column capture contract)
|
|
311
|
+
ModifiedAt: modstamp ? new Date(modstamp) : undefined,
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
MaxSystemModstamp(records) {
|
|
316
|
+
let max = null;
|
|
317
|
+
for (const r of records) {
|
|
318
|
+
const stamp = (r.Fields['SystemModstamp'] ?? r.Fields['systemModstamp']);
|
|
319
|
+
if (stamp && (!max || stamp > max))
|
|
320
|
+
max = stamp;
|
|
321
|
+
}
|
|
322
|
+
if (!max)
|
|
323
|
+
return null;
|
|
324
|
+
const parsed = new Date(max);
|
|
325
|
+
if (Number.isNaN(parsed.getTime()))
|
|
326
|
+
return max;
|
|
327
|
+
// Advance 1ms so the next `>=` filter excludes the boundary cluster (mirrors the SOQL path).
|
|
328
|
+
return new Date(parsed.getTime() + 1).toISOString();
|
|
329
|
+
}
|
|
330
|
+
BuildFDServicePath(cfg, objCfg) {
|
|
331
|
+
const wrapper = objCfg.FDServiceWrapper ?? 'Order';
|
|
332
|
+
return `${cfg.FDServiceBasePath}/${wrapper}Service`;
|
|
333
|
+
}
|
|
334
|
+
// ─── Backing-sObject resolution ──────────────────────────────────
|
|
335
|
+
/**
|
|
336
|
+
* Resolves the friendly IO `Name` to its backing Salesforce sObject API name.
|
|
337
|
+
* Reads the IO's Configuration.BackingSObject from the engine cache; falls
|
|
338
|
+
* back to a namespace-prefixed PascalSnake derivation when metadata isn't
|
|
339
|
+
* loaded (e.g. unit tests) or the IO already IS a fully-qualified sObject.
|
|
340
|
+
*/
|
|
341
|
+
ResolveBackingSObject(companyIntegration, ioName) {
|
|
342
|
+
const objCfg = this.GetObjectConfig(companyIntegration, ioName);
|
|
343
|
+
if (objCfg?.BackingSObject)
|
|
344
|
+
return objCfg.BackingSObject;
|
|
345
|
+
// Already a fully-qualified managed-package sObject — pass through unchanged.
|
|
346
|
+
if (/__c$/i.test(ioName))
|
|
347
|
+
return ioName;
|
|
348
|
+
return ioName; // best-effort: unmapped name used verbatim (describe will surface a clear error)
|
|
349
|
+
}
|
|
350
|
+
/** Reads + parses the per-IO Configuration from the engine cache. Returns null if unavailable. */
|
|
351
|
+
GetObjectConfig(companyIntegration, ioName) {
|
|
352
|
+
try {
|
|
353
|
+
const obj = IntegrationEngineBase.Instance.GetIntegrationObject(companyIntegration.IntegrationID, ioName);
|
|
354
|
+
if (!obj?.Configuration)
|
|
355
|
+
return null;
|
|
356
|
+
return JSON.parse(obj.Configuration);
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// ─── Namespace + name helpers ────────────────────────────────────
|
|
363
|
+
IsInManagedPackage(sObjectName, namespaces) {
|
|
364
|
+
const lower = sObjectName.toLowerCase();
|
|
365
|
+
return namespaces.some(ns => lower.startsWith(`${ns}__`));
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Presents a managed-package sObject API name as a friendly IO name by
|
|
369
|
+
* stripping the namespace prefix and the `__c` suffix and PascalCasing the
|
|
370
|
+
* snake segments (e.g. OrderApi__Sales_Order_Line__c → SalesOrderLine).
|
|
371
|
+
*/
|
|
372
|
+
SObjectToFriendlyName(sObjectName) {
|
|
373
|
+
const withoutNamespace = sObjectName.replace(/^[A-Za-z]+__/i, '');
|
|
374
|
+
const withoutSuffix = withoutNamespace.replace(/__c$/i, '');
|
|
375
|
+
return withoutSuffix
|
|
376
|
+
.split('_')
|
|
377
|
+
.filter(seg => seg.length > 0)
|
|
378
|
+
.map(seg => seg.charAt(0).toUpperCase() + seg.slice(1))
|
|
379
|
+
.join('');
|
|
380
|
+
}
|
|
381
|
+
/** Rewrites a fetch batch's record ObjectType from the backing sObject back to the IO name. */
|
|
382
|
+
RewriteObjectType(batch, ioName) {
|
|
383
|
+
for (const r of batch.Records)
|
|
384
|
+
r.ObjectType = ioName;
|
|
385
|
+
return batch;
|
|
386
|
+
}
|
|
387
|
+
// ─── Reuse-friendly thin wrappers over inherited protected helpers ──
|
|
388
|
+
// SalesforceConnector exposes Authenticate / BuildHeaders / MakeHTTPRequest /
|
|
389
|
+
// GetBaseURL as protected; these named wrappers keep the FDService code paths
|
|
390
|
+
// readable and route ALL FDService HTTP through the same auth + mock-redirect
|
|
391
|
+
// surface the inherited SOQL path uses (so FDService is mock-testable too).
|
|
392
|
+
async AuthenticateForFonteva(companyIntegration, contextUser) {
|
|
393
|
+
return this.Authenticate(companyIntegration, contextUser);
|
|
394
|
+
}
|
|
395
|
+
FontevaHeaders(auth) {
|
|
396
|
+
return this.BuildHeaders(auth);
|
|
397
|
+
}
|
|
398
|
+
async MakeFontevaRequest(auth, url, method, headers, body) {
|
|
399
|
+
return this.MakeHTTPRequest(auth, url, method, headers, body);
|
|
400
|
+
}
|
|
401
|
+
FontevaApiBase(auth) {
|
|
402
|
+
return this.GetBaseURL(auth.CompanyIntegration, auth);
|
|
403
|
+
}
|
|
404
|
+
PreviewFonteva(body) {
|
|
405
|
+
if (typeof body === 'string')
|
|
406
|
+
return body.slice(0, 500);
|
|
407
|
+
try {
|
|
408
|
+
return JSON.stringify(body).slice(0, 500);
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
return String(body);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
FontevaConnector = __decorate([
|
|
416
|
+
RegisterClass(BaseIntegrationConnector, '@memberjunction/connector-fonteva')
|
|
417
|
+
], FontevaConnector);
|
|
418
|
+
export { FontevaConnector };
|
|
419
|
+
/** Tree-shaking prevention: referenced from index.ts so the @RegisterClass survives bundling. */
|
|
420
|
+
export function LoadFontevaConnector() { }
|
|
421
|
+
//# sourceMappingURL=FontevaConnector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FontevaConnector.js","sourceRoot":"","sources":["../src/FontevaConnector.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './FontevaConnector.js';
|
|
2
|
+
/** Open App bootstrap entry: importing this module ran the connector's @RegisterClass decorator;
|
|
3
|
+
* this no-op satisfies the loader's required startupExport and forces the import at MJAPI boot. */
|
|
4
|
+
export declare function registerConnector(): void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './FontevaConnector.js';
|
|
2
|
+
/** Open App bootstrap entry: importing this module ran the connector's @RegisterClass decorator;
|
|
3
|
+
* this no-op satisfies the loader's required startupExport and forces the import at MJAPI boot. */
|
|
4
|
+
export function registerConnector() { }
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AAEtC;oGACoG;AACpG,MAAM,UAAU,iBAAiB,KAAiD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@memberjunction/connector-fonteva",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MemberJunction Fonteva connector.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"/dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc && tsc-alias -f",
|
|
13
|
+
"test": "vitest run --passWithNoTests"
|
|
14
|
+
},
|
|
15
|
+
"author": "MemberJunction.com",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@memberjunction/core": ">=5.42.0 <6.0.0",
|
|
19
|
+
"@memberjunction/core-entities": ">=5.42.0 <6.0.0",
|
|
20
|
+
"@memberjunction/global": ">=5.42.0 <6.0.0",
|
|
21
|
+
"@memberjunction/integration-engine": ">=5.42.0 <6.0.0",
|
|
22
|
+
"@memberjunction/integration-engine-base": ">=5.42.0 <6.0.0"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@memberjunction/connector-salesforce": "*"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "24.10.11",
|
|
29
|
+
"tsc-alias": "^1.8.16",
|
|
30
|
+
"typescript": "^5.9.3",
|
|
31
|
+
"vitest": "^4.0.18",
|
|
32
|
+
"@memberjunction/core": "^5.42.0",
|
|
33
|
+
"@memberjunction/core-entities": "^5.42.0",
|
|
34
|
+
"@memberjunction/global": "^5.42.0",
|
|
35
|
+
"@memberjunction/integration-engine": "^5.42.0",
|
|
36
|
+
"@memberjunction/integration-engine-base": "^5.42.0"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/MemberJunction/Integrations"
|
|
41
|
+
}
|
|
42
|
+
}
|