@memberjunction/integration-connectors 0.0.1 → 5.8.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.
@@ -0,0 +1,101 @@
1
+ import type { UserInfo } from '@memberjunction/core';
2
+ import type { MJCompanyIntegrationEntity } from '@memberjunction/core-entities';
3
+ import { BaseIntegrationConnector, type ConnectionTestResult, type ExternalObjectSchema, type ExternalFieldSchema, type FetchContext, type FetchBatchResult, type ExternalRecord } from '@memberjunction/integration-engine';
4
+ import sql from 'mssql';
5
+ /** Connection configuration parsed from CompanyIntegration.Configuration JSON */
6
+ export interface ConnectionConfig {
7
+ /** SQL Server hostname */
8
+ Server: string;
9
+ /** Database name */
10
+ Database: string;
11
+ /** Database user */
12
+ User: string;
13
+ /** Database password */
14
+ Password: string;
15
+ /** Database schema (e.g., 'hs', 'sf', 'ym'). Defaults to 'dbo'. */
16
+ Schema: string;
17
+ }
18
+ /**
19
+ * Abstract base class for connectors that read from relational databases via mssql.
20
+ * Handles connection management, object/field discovery, and connection testing.
21
+ * Subclasses must implement FetchChanges to define record extraction logic.
22
+ */
23
+ export declare abstract class RelationalDBConnector extends BaseIntegrationConnector {
24
+ /** Cache of open connection pools keyed by "server|database" */
25
+ private poolCache;
26
+ /**
27
+ * Parses the Configuration JSON on a CompanyIntegration to extract connection details.
28
+ * @param companyIntegration - The entity containing Configuration JSON
29
+ * @returns Parsed connection configuration
30
+ * @throws Error if Configuration is missing or malformed
31
+ */
32
+ protected ParseConnectionConfig(companyIntegration: MJCompanyIntegrationEntity): ConnectionConfig;
33
+ /**
34
+ * Opens or reuses a mssql ConnectionPool for the given configuration.
35
+ * Pools are cached by server+database to avoid redundant connections.
36
+ * @param config - Connection configuration
37
+ * @returns An open ConnectionPool
38
+ */
39
+ protected GetPool(config: ConnectionConfig): Promise<sql.ConnectionPool>;
40
+ /**
41
+ * Tests connectivity to the source database by running SELECT 1.
42
+ * @param companyIntegration - The company integration with connection configuration
43
+ * @param _contextUser - User context for authorization
44
+ * @returns Connection test result with success/failure and message
45
+ */
46
+ TestConnection(companyIntegration: MJCompanyIntegrationEntity, _contextUser: UserInfo): Promise<ConnectionTestResult>;
47
+ /**
48
+ * Discovers all user tables in the source database via INFORMATION_SCHEMA.
49
+ * @param companyIntegration - The company integration with connection configuration
50
+ * @param _contextUser - User context for authorization
51
+ * @returns Array of object schemas for each table found
52
+ */
53
+ DiscoverObjects(companyIntegration: MJCompanyIntegrationEntity, _contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
54
+ /**
55
+ * Discovers columns on a specific table via INFORMATION_SCHEMA.COLUMNS.
56
+ * @param companyIntegration - The company integration with connection configuration
57
+ * @param objectName - Table name to inspect
58
+ * @param _contextUser - User context for authorization
59
+ * @returns Array of field schemas for the specified table
60
+ */
61
+ DiscoverFields(companyIntegration: MJCompanyIntegrationEntity, objectName: string, _contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
62
+ /**
63
+ * Converts a row from INFORMATION_SCHEMA.COLUMNS to an ExternalFieldSchema.
64
+ * @param row - Column metadata row
65
+ * @returns Mapped field schema
66
+ */
67
+ private mapColumnToFieldSchema;
68
+ /**
69
+ * Builds an ExternalRecord from a SQL result row.
70
+ * @param row - Raw database row
71
+ * @param idField - Column name to use as ExternalID
72
+ * @param objectType - Object type name for the record
73
+ * @param modifiedAtField - Column name for the modification timestamp
74
+ * @param deletedField - Column name for the deleted flag (optional)
75
+ * @returns An ExternalRecord
76
+ */
77
+ protected BuildExternalRecord(row: Record<string, unknown>, idField: string, objectType: string, modifiedAtField: string, deletedField?: string): ExternalRecord;
78
+ /**
79
+ * Fetches changed records from a table, ordered by a modification timestamp column.
80
+ * Applies watermark filtering and batch size limiting.
81
+ * @param ctx - Fetch context with integration, object, watermark, and batch details
82
+ * @param idField - Column name for the primary key
83
+ * @param modifiedAtField - Column name for the modification timestamp
84
+ * @param deletedField - Column name for the deleted flag (optional)
85
+ * @returns Batch of external records with pagination info
86
+ */
87
+ protected FetchChangesFromTable(ctx: FetchContext, idField: string, modifiedAtField: string, deletedField?: string): Promise<FetchBatchResult>;
88
+ /**
89
+ * Extracts the full-precision watermark string from the last row's __mj_raw_ts column.
90
+ * Uses CONVERT(varchar, ..., 126) output which preserves datetimeoffset(7) precision,
91
+ * avoiding the sub-millisecond truncation that JavaScript Date introduces.
92
+ * @param rows - Array of database rows containing __mj_raw_ts
93
+ * @returns Full-precision datetimeoffset string, or undefined
94
+ */
95
+ private extractRawWatermark;
96
+ /**
97
+ * Closes all cached connection pools. Call during cleanup/shutdown.
98
+ */
99
+ CloseAllPools(): Promise<void>;
100
+ }
101
+ //# sourceMappingURL=RelationalDBConnector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationalDBConnector.d.ts","sourceRoot":"","sources":["../src/RelationalDBConnector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EACH,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC7B,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,8BAAsB,qBAAsB,SAAQ,wBAAwB;IACxE,gEAAgE;IAChE,OAAO,CAAC,SAAS,CAAyC;IAE1D;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,0BAA0B,GAAG,gBAAgB;IAsBjG;;;;;OAKG;cACa,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAuB9E;;;;;OAKG;IACU,cAAc,CACvB,kBAAkB,EAAE,0BAA0B,EAC9C,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,oBAAoB,CAAC;IAoBhC;;;;;OAKG;IACU,eAAe,CACxB,kBAAkB,EAAE,0BAA0B,EAC9C,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAkBlC;;;;;;OAMG;IACU,cAAc,CACvB,kBAAkB,EAAE,0BAA0B,EAC9C,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAkBjC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;;;;;;;OAQG;IACH,SAAS,CAAC,mBAAmB,CACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,MAAM,GACtB,cAAc;IAcjB;;;;;;;;OAQG;cACa,qBAAqB,CACjC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC;IAsC5B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ9C"}
@@ -0,0 +1,221 @@
1
+ import { BaseIntegrationConnector, } from '@memberjunction/integration-engine';
2
+ import sql from 'mssql';
3
+ /**
4
+ * Abstract base class for connectors that read from relational databases via mssql.
5
+ * Handles connection management, object/field discovery, and connection testing.
6
+ * Subclasses must implement FetchChanges to define record extraction logic.
7
+ */
8
+ export class RelationalDBConnector extends BaseIntegrationConnector {
9
+ constructor() {
10
+ super(...arguments);
11
+ /** Cache of open connection pools keyed by "server|database" */
12
+ this.poolCache = new Map();
13
+ }
14
+ /**
15
+ * Parses the Configuration JSON on a CompanyIntegration to extract connection details.
16
+ * @param companyIntegration - The entity containing Configuration JSON
17
+ * @returns Parsed connection configuration
18
+ * @throws Error if Configuration is missing or malformed
19
+ */
20
+ ParseConnectionConfig(companyIntegration) {
21
+ const configJson = companyIntegration.Get('Configuration');
22
+ if (!configJson) {
23
+ throw new Error('CompanyIntegration.Configuration is null or empty');
24
+ }
25
+ const parsed = JSON.parse(configJson);
26
+ const server = parsed['server'];
27
+ const database = parsed['database'];
28
+ const user = parsed['user'];
29
+ const password = parsed['password'];
30
+ const schema = parsed['schema'] ?? 'dbo';
31
+ if (!server || !database || !user || !password) {
32
+ throw new Error('Configuration JSON must contain server, database, user, and password fields');
33
+ }
34
+ return { Server: server, Database: database, User: user, Password: password, Schema: schema };
35
+ }
36
+ /**
37
+ * Opens or reuses a mssql ConnectionPool for the given configuration.
38
+ * Pools are cached by server+database to avoid redundant connections.
39
+ * @param config - Connection configuration
40
+ * @returns An open ConnectionPool
41
+ */
42
+ async GetPool(config) {
43
+ const cacheKey = `${config.Server}|${config.Database}`;
44
+ const existing = this.poolCache.get(cacheKey);
45
+ if (existing?.connected) {
46
+ return existing;
47
+ }
48
+ const pool = new sql.ConnectionPool({
49
+ server: config.Server,
50
+ database: config.Database,
51
+ user: config.User,
52
+ password: config.Password,
53
+ options: {
54
+ encrypt: false,
55
+ trustServerCertificate: true,
56
+ },
57
+ });
58
+ await pool.connect();
59
+ this.poolCache.set(cacheKey, pool);
60
+ return pool;
61
+ }
62
+ /**
63
+ * Tests connectivity to the source database by running SELECT 1.
64
+ * @param companyIntegration - The company integration with connection configuration
65
+ * @param _contextUser - User context for authorization
66
+ * @returns Connection test result with success/failure and message
67
+ */
68
+ async TestConnection(companyIntegration, _contextUser) {
69
+ try {
70
+ const config = this.ParseConnectionConfig(companyIntegration);
71
+ const pool = await this.GetPool(config);
72
+ const result = await pool.request().query('SELECT @@VERSION AS version');
73
+ const version = result.recordset[0]?.version ?? 'Unknown';
74
+ return {
75
+ Success: true,
76
+ Message: `Connected to ${config.Database} on ${config.Server}`,
77
+ ServerVersion: version.split('\n')[0],
78
+ };
79
+ }
80
+ catch (err) {
81
+ const message = err instanceof Error ? err.message : String(err);
82
+ return { Success: false, Message: `Connection failed: ${message}` };
83
+ }
84
+ }
85
+ /**
86
+ * Discovers all user tables in the source database via INFORMATION_SCHEMA.
87
+ * @param companyIntegration - The company integration with connection configuration
88
+ * @param _contextUser - User context for authorization
89
+ * @returns Array of object schemas for each table found
90
+ */
91
+ async DiscoverObjects(companyIntegration, _contextUser) {
92
+ const config = this.ParseConnectionConfig(companyIntegration);
93
+ const pool = await this.GetPool(config);
94
+ const result = await pool.request()
95
+ .input('schemaName', sql.NVarChar, config.Schema)
96
+ .query(`SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = @schemaName ORDER BY TABLE_NAME`);
97
+ return result.recordset.map((row) => ({
98
+ Name: row.TABLE_NAME,
99
+ Label: row.TABLE_NAME,
100
+ SupportsIncrementalSync: true,
101
+ SupportsWrite: false,
102
+ }));
103
+ }
104
+ /**
105
+ * Discovers columns on a specific table via INFORMATION_SCHEMA.COLUMNS.
106
+ * @param companyIntegration - The company integration with connection configuration
107
+ * @param objectName - Table name to inspect
108
+ * @param _contextUser - User context for authorization
109
+ * @returns Array of field schemas for the specified table
110
+ */
111
+ async DiscoverFields(companyIntegration, objectName, _contextUser) {
112
+ const config = this.ParseConnectionConfig(companyIntegration);
113
+ const pool = await this.GetPool(config);
114
+ const result = await pool
115
+ .request()
116
+ .input('tableName', sql.NVarChar, objectName)
117
+ .input('schemaName', sql.NVarChar, config.Schema)
118
+ .query(`SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), COLUMN_NAME, 'IsIdentity') AS IS_IDENTITY
119
+ FROM INFORMATION_SCHEMA.COLUMNS
120
+ WHERE TABLE_NAME = @tableName AND TABLE_SCHEMA = @schemaName
121
+ ORDER BY ORDINAL_POSITION`);
122
+ return result.recordset.map((row) => this.mapColumnToFieldSchema(row));
123
+ }
124
+ /**
125
+ * Converts a row from INFORMATION_SCHEMA.COLUMNS to an ExternalFieldSchema.
126
+ * @param row - Column metadata row
127
+ * @returns Mapped field schema
128
+ */
129
+ mapColumnToFieldSchema(row) {
130
+ return {
131
+ Name: row.COLUMN_NAME,
132
+ Label: row.COLUMN_NAME,
133
+ DataType: row.DATA_TYPE,
134
+ IsRequired: row.IS_NULLABLE === 'NO',
135
+ IsUniqueKey: false,
136
+ IsReadOnly: row.IS_IDENTITY === 1,
137
+ };
138
+ }
139
+ /**
140
+ * Builds an ExternalRecord from a SQL result row.
141
+ * @param row - Raw database row
142
+ * @param idField - Column name to use as ExternalID
143
+ * @param objectType - Object type name for the record
144
+ * @param modifiedAtField - Column name for the modification timestamp
145
+ * @param deletedField - Column name for the deleted flag (optional)
146
+ * @returns An ExternalRecord
147
+ */
148
+ BuildExternalRecord(row, idField, objectType, modifiedAtField, deletedField) {
149
+ const modifiedRaw = row[modifiedAtField];
150
+ const modifiedAt = modifiedRaw instanceof Date ? modifiedRaw : undefined;
151
+ const isDeleted = deletedField ? Boolean(row[deletedField]) : undefined;
152
+ return {
153
+ ExternalID: String(row[idField]),
154
+ ObjectType: objectType,
155
+ Fields: { ...row },
156
+ ModifiedAt: modifiedAt,
157
+ IsDeleted: isDeleted,
158
+ };
159
+ }
160
+ /**
161
+ * Fetches changed records from a table, ordered by a modification timestamp column.
162
+ * Applies watermark filtering and batch size limiting.
163
+ * @param ctx - Fetch context with integration, object, watermark, and batch details
164
+ * @param idField - Column name for the primary key
165
+ * @param modifiedAtField - Column name for the modification timestamp
166
+ * @param deletedField - Column name for the deleted flag (optional)
167
+ * @returns Batch of external records with pagination info
168
+ */
169
+ async FetchChangesFromTable(ctx, idField, modifiedAtField, deletedField) {
170
+ const config = this.ParseConnectionConfig(ctx.CompanyIntegration);
171
+ const pool = await this.GetPool(config);
172
+ const request = pool.request();
173
+ let whereClause = '';
174
+ if (ctx.WatermarkValue) {
175
+ whereClause = `WHERE [${modifiedAtField}] > CAST(@watermark AS datetimeoffset(7))`;
176
+ request.input('watermark', sql.NVarChar, ctx.WatermarkValue);
177
+ }
178
+ // Fetch one extra to detect HasMore
179
+ const fetchCount = ctx.BatchSize + 1;
180
+ request.input('fetchCount', sql.Int, fetchCount);
181
+ // Include full-precision timestamp (datetimeoffset has 7 decimal places, JS Date only has 3)
182
+ // to avoid sub-millisecond precision loss in watermark comparisons
183
+ const rawTsCol = `CONVERT(varchar(50), [${modifiedAtField}], 126) AS [__mj_raw_ts]`;
184
+ const query = `SELECT TOP (@fetchCount) *, ${rawTsCol} FROM [${config.Schema}].[${ctx.ObjectName}] ${whereClause} ORDER BY [${modifiedAtField}], [${idField}]`;
185
+ const result = await request.query(query);
186
+ const hasMore = result.recordset.length > ctx.BatchSize;
187
+ const rows = hasMore ? result.recordset.slice(0, ctx.BatchSize) : result.recordset;
188
+ const newWatermark = this.extractRawWatermark(rows);
189
+ // Remove internal column before building records
190
+ for (const row of rows) {
191
+ delete row['__mj_raw_ts'];
192
+ }
193
+ const records = rows.map((row) => this.BuildExternalRecord(row, idField, ctx.ObjectName, modifiedAtField, deletedField));
194
+ return { Records: records, HasMore: hasMore, NewWatermarkValue: newWatermark };
195
+ }
196
+ /**
197
+ * Extracts the full-precision watermark string from the last row's __mj_raw_ts column.
198
+ * Uses CONVERT(varchar, ..., 126) output which preserves datetimeoffset(7) precision,
199
+ * avoiding the sub-millisecond truncation that JavaScript Date introduces.
200
+ * @param rows - Array of database rows containing __mj_raw_ts
201
+ * @returns Full-precision datetimeoffset string, or undefined
202
+ */
203
+ extractRawWatermark(rows) {
204
+ if (rows.length === 0)
205
+ return undefined;
206
+ const rawTs = rows[rows.length - 1]['__mj_raw_ts'];
207
+ return rawTs != null ? String(rawTs) : undefined;
208
+ }
209
+ /**
210
+ * Closes all cached connection pools. Call during cleanup/shutdown.
211
+ */
212
+ async CloseAllPools() {
213
+ for (const pool of this.poolCache.values()) {
214
+ if (pool.connected) {
215
+ await pool.close();
216
+ }
217
+ }
218
+ this.poolCache.clear();
219
+ }
220
+ }
221
+ //# sourceMappingURL=RelationalDBConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationalDBConnector.js","sourceRoot":"","sources":["../src/RelationalDBConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type FetchContext, type FetchBatchResult, type DefaultFieldMapping } from '@memberjunction/integration-engine';
2
+ import { RelationalDBConnector } from './RelationalDBConnector.js';
3
+ /**
4
+ * Connector for Salesforce CRM data, backed by the mock_data database (sf schema).
5
+ * Reads from sf.Contact, sf.Account, and sf.Opportunity tables.
6
+ * Provides default field mappings for Contacts and Accounts to MJ entities.
7
+ */
8
+ export declare class SalesforceConnector extends RelationalDBConnector {
9
+ /**
10
+ * Fetches a batch of changed records from the specified Salesforce object table.
11
+ * Uses LastModifiedDate for watermark-based incremental sync.
12
+ * @param ctx - Fetch context with integration, object, watermark, and batch details
13
+ * @returns Batch of Salesforce records with pagination info
14
+ */
15
+ FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
16
+ /**
17
+ * Returns suggested default field mappings for known Salesforce objects to MJ entities.
18
+ * @param objectName - Salesforce object name (e.g., "Contact")
19
+ * @param _entityName - Target MJ entity name (e.g., "Contacts")
20
+ * @returns Array of default field mappings
21
+ */
22
+ GetDefaultFieldMappings(objectName: string, _entityName: string): DefaultFieldMapping[];
23
+ /** Default field mappings: sf_Contact -> Contacts */
24
+ private getContactMappings;
25
+ /** Default field mappings: sf_Account -> Companies */
26
+ private getAccountMappings;
27
+ }
28
+ //# sourceMappingURL=SalesforceConnector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SalesforceConnector.d.ts","sourceRoot":"","sources":["../src/SalesforceConnector.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAC3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AASnE;;;;GAIG;AACH,qBACa,mBAAoB,SAAQ,qBAAqB;IAC1D;;;;;OAKG;IACU,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIvE;;;;;OAKG;IACa,uBAAuB,CACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GACpB,mBAAmB,EAAE;IAWxB,qDAAqD;IACrD,OAAO,CAAC,kBAAkB;IAW1B,sDAAsD;IACtD,OAAO,CAAC,kBAAkB;CAS7B"}
@@ -0,0 +1,73 @@
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 { BaseIntegrationConnector, } from '@memberjunction/integration-engine';
9
+ import { RelationalDBConnector } from './RelationalDBConnector.js';
10
+ /** Primary key column used across all Salesforce mock tables */
11
+ const SF_ID_FIELD = 'Id';
12
+ /** Modification timestamp column used across Salesforce mock tables */
13
+ const SF_MODIFIED_FIELD = 'LastModifiedDate';
14
+ /** Soft-delete flag column used across all Salesforce mock tables */
15
+ const SF_DELETED_FIELD = 'IsDeleted';
16
+ /**
17
+ * Connector for Salesforce CRM data, backed by the mock_data database (sf schema).
18
+ * Reads from sf.Contact, sf.Account, and sf.Opportunity tables.
19
+ * Provides default field mappings for Contacts and Accounts to MJ entities.
20
+ */
21
+ let SalesforceConnector = class SalesforceConnector extends RelationalDBConnector {
22
+ /**
23
+ * Fetches a batch of changed records from the specified Salesforce object table.
24
+ * Uses LastModifiedDate for watermark-based incremental sync.
25
+ * @param ctx - Fetch context with integration, object, watermark, and batch details
26
+ * @returns Batch of Salesforce records with pagination info
27
+ */
28
+ async FetchChanges(ctx) {
29
+ return this.FetchChangesFromTable(ctx, SF_ID_FIELD, SF_MODIFIED_FIELD, SF_DELETED_FIELD);
30
+ }
31
+ /**
32
+ * Returns suggested default field mappings for known Salesforce objects to MJ entities.
33
+ * @param objectName - Salesforce object name (e.g., "Contact")
34
+ * @param _entityName - Target MJ entity name (e.g., "Contacts")
35
+ * @returns Array of default field mappings
36
+ */
37
+ GetDefaultFieldMappings(objectName, _entityName) {
38
+ switch (objectName) {
39
+ case 'Contact':
40
+ return this.getContactMappings();
41
+ case 'Account':
42
+ return this.getAccountMappings();
43
+ default:
44
+ return [];
45
+ }
46
+ }
47
+ /** Default field mappings: sf_Contact -> Contacts */
48
+ getContactMappings() {
49
+ return [
50
+ { SourceFieldName: 'Email', DestinationFieldName: 'Email', IsKeyField: true },
51
+ { SourceFieldName: 'FirstName', DestinationFieldName: 'FirstName' },
52
+ { SourceFieldName: 'LastName', DestinationFieldName: 'LastName' },
53
+ { SourceFieldName: 'Phone', DestinationFieldName: 'Phone' },
54
+ { SourceFieldName: 'Title', DestinationFieldName: 'Title' },
55
+ { SourceFieldName: 'Department', DestinationFieldName: 'Department' },
56
+ ];
57
+ }
58
+ /** Default field mappings: sf_Account -> Companies */
59
+ getAccountMappings() {
60
+ return [
61
+ { SourceFieldName: 'Name', DestinationFieldName: 'Name', IsKeyField: true },
62
+ { SourceFieldName: 'Industry', DestinationFieldName: 'Industry' },
63
+ { SourceFieldName: 'BillingCity', DestinationFieldName: 'City' },
64
+ { SourceFieldName: 'BillingState', DestinationFieldName: 'State' },
65
+ { SourceFieldName: 'Phone', DestinationFieldName: 'Phone' },
66
+ ];
67
+ }
68
+ };
69
+ SalesforceConnector = __decorate([
70
+ RegisterClass(BaseIntegrationConnector, 'SalesforceConnector')
71
+ ], SalesforceConnector);
72
+ export { SalesforceConnector };
73
+ //# sourceMappingURL=SalesforceConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SalesforceConnector.js","sourceRoot":"","sources":["../src/SalesforceConnector.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACH,wBAAwB,GAI3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,gEAAgE;AAChE,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,uEAAuE;AACvE,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAC7C,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC;;;;GAIG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,qBAAqB;IAC1D;;;;;OAKG;IACI,KAAK,CAAC,YAAY,CAAC,GAAiB;QACvC,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAC7F,CAAC;IAED;;;;;OAKG;IACa,uBAAuB,CACnC,UAAkB,EAClB,WAAmB;QAEnB,QAAQ,UAAU,EAAE,CAAC;YACjB,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACrC,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACrC;gBACI,OAAO,EAAE,CAAC;QAClB,CAAC;IACL,CAAC;IAED,qDAAqD;IAC7C,kBAAkB;QACtB,OAAO;YACH,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE;YAC7E,EAAE,eAAe,EAAE,WAAW,EAAE,oBAAoB,EAAE,WAAW,EAAE;YACnE,EAAE,eAAe,EAAE,UAAU,EAAE,oBAAoB,EAAE,UAAU,EAAE;YACjE,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE;YAC3D,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE;YAC3D,EAAE,eAAe,EAAE,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE;SACxE,CAAC;IACN,CAAC;IAED,sDAAsD;IAC9C,kBAAkB;QACtB,OAAO;YACH,EAAE,eAAe,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE;YAC3E,EAAE,eAAe,EAAE,UAAU,EAAE,oBAAoB,EAAE,UAAU,EAAE;YACjE,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAE;YAChE,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,OAAO,EAAE;YAClE,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE;SAC9D,CAAC;IACN,CAAC;CACJ,CAAA;AArDY,mBAAmB;IAD/B,aAAa,CAAC,wBAAwB,EAAE,qBAAqB,CAAC;GAClD,mBAAmB,CAqD/B"}
@@ -0,0 +1,76 @@
1
+ import type { UserInfo } from '@memberjunction/core';
2
+ import type { MJCompanyIntegrationEntity } from '@memberjunction/core-entities';
3
+ import { BaseIntegrationConnector, type ConnectionTestResult, type ExternalObjectSchema, type ExternalFieldSchema, type FetchContext, type FetchBatchResult, type DefaultFieldMapping } from '@memberjunction/integration-engine';
4
+ /** Connection configuration parsed from CompanyIntegration.Configuration JSON */
5
+ export interface YMConnectionConfig {
6
+ /** YM client/site identifier (integer) */
7
+ ClientID: string;
8
+ /** YM API key (used as UserName for session auth) */
9
+ APIKey: string;
10
+ /** YM API password (used as Password for session auth) */
11
+ APIPassword: string;
12
+ }
13
+ /**
14
+ * Connector for the YourMembership (YM) AMS REST API.
15
+ *
16
+ * Auth flow:
17
+ * 1. POST /Ams/Authenticate with credentials + ClientID
18
+ * 2. Receive SessionId
19
+ * 3. Pass SessionId as X-SS-ID header on all data requests
20
+ *
21
+ * Configuration JSON: { "ClientID": "25363", "APIKey": "...", "APIPassword": "..." }
22
+ */
23
+ export declare class YourMembershipConnector extends BaseIntegrationConnector {
24
+ /** Session cache keyed by ClientID */
25
+ private sessionCache;
26
+ /**
27
+ * Parses the Configuration JSON from a CompanyIntegration entity.
28
+ */
29
+ protected ParseConfig(companyIntegration: MJCompanyIntegrationEntity): YMConnectionConfig;
30
+ /** Obtains or reuses a YM session for the given credentials. */
31
+ protected GetSession(config: YMConnectionConfig): Promise<string>;
32
+ /** Creates a new YM session via the Authenticate endpoint. */
33
+ private CreateSession;
34
+ /** Invalidates a cached session so the next request re-authenticates. */
35
+ protected InvalidateSession(clientId: string): void;
36
+ /**
37
+ * Makes a GET request to a YM API endpoint using session auth.
38
+ * Retries once on 401 (session expiry).
39
+ */
40
+ protected MakeRequest(config: YMConnectionConfig, endpoint: string, queryParams?: Record<string, string>): Promise<Record<string, unknown>>;
41
+ private FetchWithSession;
42
+ private BuildUrl;
43
+ private CheckResponseError;
44
+ /** Tests connectivity by authenticating and fetching ClientConfig. */
45
+ TestConnection(companyIntegration: MJCompanyIntegrationEntity, _contextUser: UserInfo): Promise<ConnectionTestResult>;
46
+ /** Returns all known YM object types available for integration. */
47
+ DiscoverObjects(_companyIntegration: MJCompanyIntegrationEntity, _contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
48
+ /** Returns the known field schema for a YM object. */
49
+ DiscoverFields(_companyIntegration: MJCompanyIntegrationEntity, objectName: string, _contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
50
+ /**
51
+ * Fetches a batch of records from a YM API endpoint.
52
+ *
53
+ * For paginated endpoints (Members, Events, Certifications), uses
54
+ * PageSize/PageNumber. The watermark tracks the current page number
55
+ * for resuming large fetches across batches.
56
+ *
57
+ * For non-paginated endpoints (MemberTypes, Memberships, Groups, Products),
58
+ * fetches all data in one call.
59
+ */
60
+ FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
61
+ /** Fetches data from a paginated YM endpoint. Watermark = page number. */
62
+ private FetchPaginated;
63
+ /** Fetches all data from a non-paginated endpoint in a single request. */
64
+ private FetchAll;
65
+ /** Fetches endpoints that return a raw JSON array (e.g., Products). */
66
+ private FetchRawArray;
67
+ /**
68
+ * Fetches Groups, which have a nested structure: GroupTypeList → Groups.
69
+ * Flattens into individual group records with the GroupType name attached.
70
+ */
71
+ private FetchGroups;
72
+ /** Returns suggested default field mappings for YM objects to MJ entities. */
73
+ GetDefaultFieldMappings(objectName: string, _entityName: string): DefaultFieldMapping[];
74
+ private BuildRecord;
75
+ }
76
+ //# sourceMappingURL=YourMembershipConnector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"YourMembershipConnector.d.ts","sourceRoot":"","sources":["../src/YourMembershipConnector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EACH,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAErB,KAAK,mBAAmB,EAC3B,MAAM,oCAAoC,CAAC;AAI5C,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IAC/B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;CACvB;AA+MD;;;;;;;;;GASG;AACH,qBACa,uBAAwB,SAAQ,wBAAwB;IACjE,sCAAsC;IACtC,OAAO,CAAC,YAAY,CAAgC;IAIpD;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,kBAAkB,EAAE,0BAA0B,GAAG,kBAAkB;IAoBzF,gEAAgE;cAChD,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQvE,8DAA8D;YAChD,aAAa;IAsC3B,yEAAyE;IACzE,SAAS,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMnD;;;OAGG;cACa,WAAW,CACvB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAqBrB,gBAAgB;IAO9B,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,kBAAkB;IAS1B,sEAAsE;IACzD,cAAc,CACvB,kBAAkB,EAAE,0BAA0B,EAC9C,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,oBAAoB,CAAC;IAkBhC,mEAAmE;IACtD,eAAe,CACxB,mBAAmB,EAAE,0BAA0B,EAC/C,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC;IASlC,sDAAsD;IACzC,cAAc,CACvB,mBAAmB,EAAE,0BAA0B,EAC/C,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,QAAQ,GACvB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAIjC;;;;;;;;;OASG;IACU,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuBvE,0EAA0E;YAC5D,cAAc;IA+B5B,0EAA0E;YAC5D,QAAQ;IAmBtB,uEAAuE;YACzD,aAAa;IAyB3B;;;OAGG;YACW,WAAW;IA4BzB,8EAA8E;IAC9D,uBAAuB,CACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GACpB,mBAAmB,EAAE;IAyBxB,OAAO,CAAC,WAAW;CAYtB"}