@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.
- package/README.md +107 -28
- package/dist/FileFeedConnector.d.ts +64 -0
- package/dist/FileFeedConnector.d.ts.map +1 -0
- package/dist/FileFeedConnector.js +190 -0
- package/dist/FileFeedConnector.js.map +1 -0
- package/dist/HubSpotConnector.d.ts +41 -0
- package/dist/HubSpotConnector.d.ts.map +1 -0
- package/dist/HubSpotConnector.js +104 -0
- package/dist/HubSpotConnector.js.map +1 -0
- package/dist/RelationalDBConnector.d.ts +101 -0
- package/dist/RelationalDBConnector.d.ts.map +1 -0
- package/dist/RelationalDBConnector.js +221 -0
- package/dist/RelationalDBConnector.js.map +1 -0
- package/dist/SalesforceConnector.d.ts +28 -0
- package/dist/SalesforceConnector.d.ts.map +1 -0
- package/dist/SalesforceConnector.js +73 -0
- package/dist/SalesforceConnector.js.map +1 -0
- package/dist/YourMembershipConnector.d.ts +76 -0
- package/dist/YourMembershipConnector.d.ts.map +1 -0
- package/dist/YourMembershipConnector.js +462 -0
- package/dist/YourMembershipConnector.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -7
|
@@ -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"}
|