@memberjunction/integration-engine 0.0.1 → 5.9.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.
Files changed (50) hide show
  1. package/README.md +142 -28
  2. package/dist/BaseIntegrationConnector.d.ts +177 -0
  3. package/dist/BaseIntegrationConnector.d.ts.map +1 -0
  4. package/dist/BaseIntegrationConnector.js +110 -0
  5. package/dist/BaseIntegrationConnector.js.map +1 -0
  6. package/dist/BaseRESTIntegrationConnector.d.ts +222 -0
  7. package/dist/BaseRESTIntegrationConnector.d.ts.map +1 -0
  8. package/dist/BaseRESTIntegrationConnector.js +482 -0
  9. package/dist/BaseRESTIntegrationConnector.js.map +1 -0
  10. package/dist/ConnectorFactory.d.ts +28 -0
  11. package/dist/ConnectorFactory.d.ts.map +1 -0
  12. package/dist/ConnectorFactory.js +42 -0
  13. package/dist/ConnectorFactory.js.map +1 -0
  14. package/dist/FieldMappingEngine.d.ts +94 -0
  15. package/dist/FieldMappingEngine.d.ts.map +1 -0
  16. package/dist/FieldMappingEngine.js +250 -0
  17. package/dist/FieldMappingEngine.js.map +1 -0
  18. package/dist/IntegrationEngine.d.ts +173 -0
  19. package/dist/IntegrationEngine.d.ts.map +1 -0
  20. package/dist/IntegrationEngine.js +677 -0
  21. package/dist/IntegrationEngine.js.map +1 -0
  22. package/dist/MatchEngine.d.ts +51 -0
  23. package/dist/MatchEngine.d.ts.map +1 -0
  24. package/dist/MatchEngine.js +129 -0
  25. package/dist/MatchEngine.js.map +1 -0
  26. package/dist/RetryRunner.d.ts +27 -0
  27. package/dist/RetryRunner.d.ts.map +1 -0
  28. package/dist/RetryRunner.js +59 -0
  29. package/dist/RetryRunner.js.map +1 -0
  30. package/dist/WatermarkService.d.ts +44 -0
  31. package/dist/WatermarkService.d.ts.map +1 -0
  32. package/dist/WatermarkService.js +97 -0
  33. package/dist/WatermarkService.js.map +1 -0
  34. package/dist/entity-types.d.ts +90 -0
  35. package/dist/entity-types.d.ts.map +1 -0
  36. package/dist/entity-types.js +13 -0
  37. package/dist/entity-types.js.map +1 -0
  38. package/dist/index.d.ts +16 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +19 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/transforms.d.ts +75 -0
  43. package/dist/transforms.d.ts.map +1 -0
  44. package/dist/transforms.js +2 -0
  45. package/dist/transforms.js.map +1 -0
  46. package/dist/types.d.ts +196 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +44 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +30 -7
package/README.md CHANGED
@@ -1,45 +1,159 @@
1
1
  # @memberjunction/integration-engine
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ MemberJunction Integration Engine — orchestration, field mapping, and connector framework for synchronizing external systems with MJ entities.
4
+
5
+ ## Architecture
6
+
7
+ The integration engine follows a pipeline architecture:
4
8
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
9
+ ```
10
+ External System → Connector → FieldMappingEngine → MatchEngine → MJ Entity Persistence
11
+ ```
6
12
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
13
+ ### Core Components
14
+
15
+ | Component | Responsibility |
16
+ |-----------|---------------|
17
+ | `BaseIntegrationConnector` | Abstract base for external system connectors |
18
+ | `ConnectorFactory` | Resolves connector instances via MJGlobal.ClassFactory |
19
+ | `FieldMappingEngine` | Applies field-level transformations from external→MJ fields |
20
+ | `MatchEngine` | Determines Create/Update/Delete/Skip for each record |
21
+ | `WatermarkService` | Manages incremental sync watermarks |
22
+ | `IntegrationOrchestrator` | Top-level coordinator that runs end-to-end sync |
23
+
24
+ ## Quick Start
25
+
26
+ ```typescript
27
+ import { IntegrationOrchestrator } from '@memberjunction/integration-engine';
28
+
29
+ const orchestrator = new IntegrationOrchestrator();
30
+ const result = await orchestrator.RunSync(companyIntegrationID, contextUser, 'Manual');
31
+
32
+ console.log(`Processed: ${result.RecordsProcessed}`);
33
+ console.log(`Created: ${result.RecordsCreated}, Updated: ${result.RecordsUpdated}`);
34
+ console.log(`Errors: ${result.RecordsErrored}`);
35
+ ```
36
+
37
+ ## Creating a Custom Connector
38
+
39
+ ```typescript
40
+ import { RegisterClass } from '@memberjunction/global';
41
+ import {
42
+ BaseIntegrationConnector,
43
+ ConnectionTestResult,
44
+ ExternalObjectSchema,
45
+ ExternalFieldSchema,
46
+ FetchContext,
47
+ FetchBatchResult,
48
+ } from '@memberjunction/integration-engine';
8
49
 
9
- ## Purpose
50
+ @RegisterClass(BaseIntegrationConnector, 'HubSpotConnector')
51
+ export class HubSpotConnector extends BaseIntegrationConnector {
52
+ async TestConnection(companyIntegration, contextUser): Promise<ConnectionTestResult> {
53
+ // Test HubSpot API connectivity
54
+ }
10
55
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/integration-engine`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
56
+ async DiscoverObjects(companyIntegration, contextUser): Promise<ExternalObjectSchema[]> {
57
+ // Return available HubSpot objects (Contacts, Companies, Deals, etc.)
58
+ }
15
59
 
16
- ## What is OIDC Trusted Publishing?
60
+ async DiscoverFields(companyIntegration, objectName, contextUser): Promise<ExternalFieldSchema[]> {
61
+ // Return fields for a specific HubSpot object
62
+ }
17
63
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
64
+ async FetchChanges(ctx: FetchContext): Promise<FetchBatchResult> {
65
+ // Fetch changed records using HubSpot's API with watermark-based pagination
66
+ }
67
+ }
68
+ ```
19
69
 
20
- ## Setup Instructions
70
+ ## Transform Types
21
71
 
22
- To properly configure OIDC trusted publishing for this package:
72
+ The `FieldMappingEngine` supports 9 transform types configured via JSON in the `TransformPipeline` field:
23
73
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
74
+ | Type | Description | Config |
75
+ |------|-------------|--------|
76
+ | `direct` | Pass-through with optional default | `{ DefaultValue?: unknown }` |
77
+ | `regex` | Regex find/replace | `{ Pattern, Replacement, Flags? }` |
78
+ | `split` | Split string, extract by index | `{ Delimiter, Index }` |
79
+ | `combine` | Merge multiple fields | `{ SourceFields, Separator }` |
80
+ | `lookup` | Case-insensitive value mapping | `{ Map, Default? }` |
81
+ | `format` | Date/number formatting | `{ FormatString, FormatType }` |
82
+ | `coerce` | Type conversion | `{ TargetType: 'string'|'number'|'boolean'|'date' }` |
83
+ | `substring` | Extract portion of string | `{ Start, Length? }` |
84
+ | `custom` | JavaScript expression | `{ Expression }` |
28
85
 
29
- ## DO NOT USE THIS PACKAGE
86
+ ### Transform Pipeline Example
30
87
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
88
+ ```json
89
+ [
90
+ { "Type": "regex", "Config": { "Pattern": "[^0-9]", "Replacement": "", "Flags": "g" } },
91
+ { "Type": "substring", "Config": { "Start": 0, "Length": 3 } }
92
+ ]
93
+ ```
36
94
 
37
- ## More Information
95
+ This pipeline strips non-numeric characters then extracts the first 3 digits (e.g., area code from phone number).
38
96
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
97
+ ### Error Handling
42
98
 
43
- ---
99
+ Each transform step can specify `OnError`:
100
+ - `"Fail"` (default) — throws, halting the record
101
+ - `"Skip"` — skips the field entirely
102
+ - `"Null"` — sets the field to null
44
103
 
45
- **Maintained for OIDC setup purposes only**
104
+ ## API Reference
105
+
106
+ ### Notifications
107
+
108
+ After a sync completes or fails, an optional `onNotification` callback receives a `SyncNotification` with pre-formatted subject and body text suitable for email delivery:
109
+
110
+ ```typescript
111
+ const result = await orchestrator.RunSync(
112
+ companyIntegrationID, contextUser, 'Scheduled',
113
+ undefined, // onProgress
114
+ (notification) => {
115
+ if (notification.Severity !== 'Info') {
116
+ emailService.send({
117
+ to: 'ops@example.com',
118
+ subject: notification.Subject,
119
+ text: notification.Body,
120
+ });
121
+ }
122
+ }
123
+ );
124
+ ```
125
+
126
+ **SyncNotification** properties:
127
+ - `Event`: `'SyncCompleted'` | `'SyncCompletedWithErrors'` | `'SyncFailed'`
128
+ - `Severity`: `'Info'` | `'Warning'` | `'Error'`
129
+ - `Subject` / `Body`: human-readable text ready for email
130
+ - `Result`: the full `SyncResult` for programmatic access
131
+
132
+ ### IntegrationOrchestrator
133
+
134
+ - `RunSync(companyIntegrationID, contextUser, triggerType?, onProgress?, onNotification?)` — Executes a full sync run
135
+
136
+ ### FieldMappingEngine
137
+
138
+ - `Apply(records, fieldMaps, entityName)` — Maps external records to MJ entity fields
139
+
140
+ ### MatchEngine
141
+
142
+ - `Resolve(records, entityMap, fieldMaps, contextUser)` — Resolves Create/Update/Delete/Skip
143
+
144
+ ### WatermarkService
145
+
146
+ - `Load(entityMapID, contextUser)` — Loads current watermark
147
+ - `Update(entityMapID, newValue, contextUser)` — Updates or creates watermark
148
+
149
+ ### ConnectorFactory
150
+
151
+ - `Resolve(integration, sourceTypes)` — Creates connector instance via ClassFactory
152
+
153
+ ### BaseIntegrationConnector (abstract)
154
+
155
+ - `TestConnection(companyIntegration, contextUser)` — Tests external system connectivity
156
+ - `DiscoverObjects(companyIntegration, contextUser)` — Lists available external objects
157
+ - `DiscoverFields(companyIntegration, objectName, contextUser)` — Lists fields on an object
158
+ - `FetchChanges(ctx)` — Fetches a batch of changed records
159
+ - `GetDefaultFieldMappings(objectName, entityName)` — Suggests default mappings
@@ -0,0 +1,177 @@
1
+ import type { UserInfo } from '@memberjunction/core';
2
+ import type { MJCompanyIntegrationEntity } from '@memberjunction/core-entities';
3
+ import type { ExternalRecord, DefaultFieldMapping, SourceSchemaInfo } from './types.js';
4
+ /** Result of testing a connection to an external system */
5
+ export interface ConnectionTestResult {
6
+ /** Whether the connection was successful */
7
+ Success: boolean;
8
+ /** Human-readable status message */
9
+ Message: string;
10
+ /** Server or API version reported by the external system */
11
+ ServerVersion?: string;
12
+ }
13
+ /** Schema description of an object/table in an external system */
14
+ export interface ExternalObjectSchema {
15
+ /** API name of the object (e.g., "Contact", "Account") */
16
+ Name: string;
17
+ /** Human-readable label */
18
+ Label: string;
19
+ /** Human-readable description of the object's purpose */
20
+ Description?: string;
21
+ /** Whether this object supports incremental sync via watermarks */
22
+ SupportsIncrementalSync: boolean;
23
+ /** Whether this object can be created/updated from MJ (push) */
24
+ SupportsWrite: boolean;
25
+ }
26
+ /** Schema description of a single field on an external object */
27
+ export interface ExternalFieldSchema {
28
+ /** API name of the field */
29
+ Name: string;
30
+ /** Human-readable label */
31
+ Label: string;
32
+ /** Human-readable description of the field's purpose */
33
+ Description?: string;
34
+ /** Field data type in the external system */
35
+ DataType: string;
36
+ /** Whether the field is required */
37
+ IsRequired: boolean;
38
+ /** Whether the field is a unique identifier */
39
+ IsUniqueKey: boolean;
40
+ /** Whether the field is read-only */
41
+ IsReadOnly: boolean;
42
+ /** Whether this field is a foreign key */
43
+ IsForeignKey?: boolean;
44
+ /** If FK, which source object it references */
45
+ ForeignKeyTarget?: string | null;
46
+ }
47
+ /** Context passed to FetchChanges for incremental data retrieval */
48
+ export interface FetchContext {
49
+ /** The company integration entity providing connection details */
50
+ CompanyIntegration: MJCompanyIntegrationEntity;
51
+ /** External object name to fetch from */
52
+ ObjectName: string;
53
+ /** Current watermark value for incremental fetch, or null for full fetch */
54
+ WatermarkValue: string | null;
55
+ /** Maximum number of records to fetch in a single batch */
56
+ BatchSize: number;
57
+ /** User context for authorization */
58
+ ContextUser: UserInfo;
59
+ }
60
+ /** Result of a FetchChanges call, containing a batch of records */
61
+ export interface FetchBatchResult {
62
+ /** Records retrieved in this batch */
63
+ Records: ExternalRecord[];
64
+ /** Whether there are more records to fetch after this batch */
65
+ HasMore: boolean;
66
+ /** Updated watermark value after this batch */
67
+ NewWatermarkValue?: string;
68
+ }
69
+ /** Configurable timeout values for connector operations */
70
+ export interface OperationTimeouts {
71
+ /** Timeout for TestConnection in milliseconds. Default: 5000 */
72
+ TestConnectionMs: number;
73
+ /** Timeout for DiscoverObjects in milliseconds. Default: 10000 */
74
+ DiscoverObjectsMs: number;
75
+ /** Timeout for DiscoverFields in milliseconds. Default: 10000 */
76
+ DiscoverFieldsMs: number;
77
+ /** Timeout for FetchChanges in milliseconds. Default: 30000 */
78
+ FetchChangesMs: number;
79
+ }
80
+ /** Default timeout values for connector operations */
81
+ export declare const DEFAULT_OPERATION_TIMEOUTS: OperationTimeouts;
82
+ /**
83
+ * Wraps a promise with a timeout. Rejects with a timeout error if the
84
+ * promise does not resolve within the specified duration.
85
+ *
86
+ * @param promise - The promise to wrap
87
+ * @param timeoutMs - Timeout in milliseconds
88
+ * @param operationName - Name of the operation for error messaging
89
+ * @returns The result of the promise
90
+ * @throws Error if the operation times out
91
+ */
92
+ export declare function WithTimeout<T>(promise: Promise<T>, timeoutMs: number, operationName: string): Promise<T>;
93
+ /** Proposed default configuration for a quick-start setup */
94
+ export interface DefaultObjectConfig {
95
+ /** Source object name in the external system */
96
+ SourceObjectName: string;
97
+ /** Proposed target table name in the MJ database */
98
+ TargetTableName: string;
99
+ /** Proposed MJ entity name */
100
+ TargetEntityName: string;
101
+ /** Whether to enable sync by default */
102
+ SyncEnabled: boolean;
103
+ /** Proposed field mappings */
104
+ FieldMappings: DefaultFieldMapping[];
105
+ }
106
+ /** Full default configuration returned by a connector for quick setup */
107
+ export interface DefaultIntegrationConfig {
108
+ /** Proposed DB schema name for new tables (e.g., "YourMembership", "HubSpot") */
109
+ DefaultSchemaName: string;
110
+ /** Objects to sync by default with proposed table/entity names */
111
+ DefaultObjects: DefaultObjectConfig[];
112
+ }
113
+ /**
114
+ * Abstract base class for integration connectors.
115
+ * Each external system (HubSpot, Salesforce, etc.) implements this class
116
+ * to provide system-specific data access and discovery.
117
+ */
118
+ export declare abstract class BaseIntegrationConnector {
119
+ /**
120
+ * Tests connectivity to the external system.
121
+ * @param companyIntegration - The company integration entity with connection credentials
122
+ * @param contextUser - User context for authorization
123
+ * @returns Connection test result with success/failure and message
124
+ */
125
+ abstract TestConnection(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ConnectionTestResult>;
126
+ /**
127
+ * Discovers available objects/tables in the external system.
128
+ * @param companyIntegration - The company integration entity with connection credentials
129
+ * @param contextUser - User context for authorization
130
+ * @returns Array of object schemas available for integration
131
+ */
132
+ abstract DiscoverObjects(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<ExternalObjectSchema[]>;
133
+ /**
134
+ * Discovers fields on a specific external object.
135
+ * @param companyIntegration - The company integration entity with connection credentials
136
+ * @param objectName - Name of the external object to inspect
137
+ * @param contextUser - User context for authorization
138
+ * @returns Array of field schemas for the specified object
139
+ */
140
+ abstract DiscoverFields(companyIntegration: MJCompanyIntegrationEntity, objectName: string, contextUser: UserInfo): Promise<ExternalFieldSchema[]>;
141
+ /**
142
+ * Fetches a batch of changed records from the external system.
143
+ * Supports incremental fetching via watermarks.
144
+ * @param ctx - Context containing connection info, object name, and watermark
145
+ * @returns Batch of external records with pagination info
146
+ */
147
+ abstract FetchChanges(ctx: FetchContext): Promise<FetchBatchResult>;
148
+ /**
149
+ * Returns suggested default field mappings for an external object to MJ entity.
150
+ * Override in subclasses to provide intelligent defaults.
151
+ * @param _objectName - Name of the external object
152
+ * @param _entityName - Name of the target MJ entity
153
+ * @returns Array of default field mappings (empty by default)
154
+ */
155
+ GetDefaultFieldMappings(_objectName: string, _entityName: string): DefaultFieldMapping[];
156
+ /**
157
+ * Returns a proposed default configuration for quick setup.
158
+ * Override in subclasses to provide connector-specific defaults
159
+ * including schema name, objects to sync, and field mappings.
160
+ * Returns null by default (no quick setup available).
161
+ */
162
+ GetDefaultConfiguration(): DefaultIntegrationConfig | null;
163
+ /**
164
+ * Introspects the source system's schema — returns metadata about available
165
+ * objects, their fields, primary keys, and foreign key relationships.
166
+ * Used by the Schema Builder to generate local DDL.
167
+ *
168
+ * Default implementation builds SourceSchemaInfo from DiscoverObjects + DiscoverFields.
169
+ * Override in subclasses for richer metadata (e.g., FK relationships, type details).
170
+ *
171
+ * @param companyIntegration - The company integration entity with connection credentials
172
+ * @param contextUser - User context for authorization
173
+ * @returns Full schema info for all source objects
174
+ */
175
+ IntrospectSchema(companyIntegration: MJCompanyIntegrationEntity, contextUser: UserInfo): Promise<SourceSchemaInfo>;
176
+ }
177
+ //# sourceMappingURL=BaseIntegrationConnector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseIntegrationConnector.d.ts","sourceRoot":"","sources":["../src/BaseIntegrationConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /** Default timeout values for connector operations */
2
+ export const DEFAULT_OPERATION_TIMEOUTS = {
3
+ TestConnectionMs: 5000,
4
+ DiscoverObjectsMs: 10000,
5
+ DiscoverFieldsMs: 10000,
6
+ FetchChangesMs: 30000,
7
+ };
8
+ /**
9
+ * Wraps a promise with a timeout. Rejects with a timeout error if the
10
+ * promise does not resolve within the specified duration.
11
+ *
12
+ * @param promise - The promise to wrap
13
+ * @param timeoutMs - Timeout in milliseconds
14
+ * @param operationName - Name of the operation for error messaging
15
+ * @returns The result of the promise
16
+ * @throws Error if the operation times out
17
+ */
18
+ export async function WithTimeout(promise, timeoutMs, operationName) {
19
+ let timeoutHandle;
20
+ const timeoutPromise = new Promise((_resolve, reject) => {
21
+ timeoutHandle = setTimeout(() => {
22
+ reject(new Error(`Operation '${operationName}' timed out after ${timeoutMs}ms`));
23
+ }, timeoutMs);
24
+ });
25
+ try {
26
+ const result = await Promise.race([promise, timeoutPromise]);
27
+ return result;
28
+ }
29
+ finally {
30
+ if (timeoutHandle !== undefined) {
31
+ clearTimeout(timeoutHandle);
32
+ }
33
+ }
34
+ }
35
+ /**
36
+ * Abstract base class for integration connectors.
37
+ * Each external system (HubSpot, Salesforce, etc.) implements this class
38
+ * to provide system-specific data access and discovery.
39
+ */
40
+ export class BaseIntegrationConnector {
41
+ /**
42
+ * Returns suggested default field mappings for an external object to MJ entity.
43
+ * Override in subclasses to provide intelligent defaults.
44
+ * @param _objectName - Name of the external object
45
+ * @param _entityName - Name of the target MJ entity
46
+ * @returns Array of default field mappings (empty by default)
47
+ */
48
+ GetDefaultFieldMappings(_objectName, _entityName) {
49
+ return [];
50
+ }
51
+ /**
52
+ * Returns a proposed default configuration for quick setup.
53
+ * Override in subclasses to provide connector-specific defaults
54
+ * including schema name, objects to sync, and field mappings.
55
+ * Returns null by default (no quick setup available).
56
+ */
57
+ GetDefaultConfiguration() {
58
+ return null;
59
+ }
60
+ /**
61
+ * Introspects the source system's schema — returns metadata about available
62
+ * objects, their fields, primary keys, and foreign key relationships.
63
+ * Used by the Schema Builder to generate local DDL.
64
+ *
65
+ * Default implementation builds SourceSchemaInfo from DiscoverObjects + DiscoverFields.
66
+ * Override in subclasses for richer metadata (e.g., FK relationships, type details).
67
+ *
68
+ * @param companyIntegration - The company integration entity with connection credentials
69
+ * @param contextUser - User context for authorization
70
+ * @returns Full schema info for all source objects
71
+ */
72
+ async IntrospectSchema(companyIntegration, contextUser) {
73
+ const objects = await this.DiscoverObjects(companyIntegration, contextUser);
74
+ const result = { Objects: [] };
75
+ for (const obj of objects) {
76
+ let fields;
77
+ try {
78
+ fields = await this.DiscoverFields(companyIntegration, obj.Name, contextUser);
79
+ }
80
+ catch (err) {
81
+ const msg = err instanceof Error ? err.message : String(err);
82
+ console.warn(`WARNING: Skipping object "${obj.Name}" — DiscoverFields failed: ${msg}`);
83
+ continue;
84
+ }
85
+ result.Objects.push({
86
+ ExternalName: obj.Name,
87
+ ExternalLabel: obj.Label,
88
+ Description: obj.Description,
89
+ Fields: fields.map(f => ({
90
+ Name: f.Name,
91
+ Label: f.Label,
92
+ Description: f.Description,
93
+ SourceType: f.DataType,
94
+ IsRequired: f.IsRequired,
95
+ MaxLength: null,
96
+ Precision: null,
97
+ Scale: null,
98
+ DefaultValue: null,
99
+ IsPrimaryKey: f.IsUniqueKey,
100
+ IsForeignKey: f.IsForeignKey ?? false,
101
+ ForeignKeyTarget: f.ForeignKeyTarget ?? null,
102
+ })),
103
+ PrimaryKeyFields: fields.filter(f => f.IsUniqueKey).map(f => f.Name),
104
+ Relationships: [],
105
+ });
106
+ }
107
+ return result;
108
+ }
109
+ }
110
+ //# sourceMappingURL=BaseIntegrationConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseIntegrationConnector.js","sourceRoot":"","sources":["../src/BaseIntegrationConnector.ts"],"names":[],"mappings":"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"}