@memberjunction/server 5.30.1 → 5.31.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/agents/skip-sdk.d.ts +17 -1
- package/dist/agents/skip-sdk.d.ts.map +1 -1
- package/dist/agents/skip-sdk.js +18 -5
- package/dist/agents/skip-sdk.js.map +1 -1
- package/dist/auth/exampleNewUserSubClass.js +1 -1
- package/dist/auth/exampleNewUserSubClass.js.map +1 -1
- package/dist/auth/index.js +2 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/newUsers.js +2 -2
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/context.js +3 -3
- package/dist/context.js.map +1 -1
- package/dist/generated/generated.d.ts +218 -8
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +1267 -52
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +5 -5
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +21 -18
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -8
- package/dist/index.js.map +1 -1
- package/dist/multiTenancy/index.js +1 -1
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/resolvers/APIKeyResolver.d.ts.map +1 -1
- package/dist/resolvers/APIKeyResolver.js +5 -3
- package/dist/resolvers/APIKeyResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts +3 -3
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +18 -12
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.d.ts +1 -1
- package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js +6 -4
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.js +2 -2
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +1 -2
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/ISAEntityResolver.d.ts.map +1 -1
- package/dist/resolvers/ISAEntityResolver.js +2 -5
- package/dist/resolvers/ISAEntityResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +75 -66
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts +4 -4
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +9 -8
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +6 -6
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +22 -18
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/TagGovernanceResolver.d.ts +43 -0
- package/dist/resolvers/TagGovernanceResolver.d.ts.map +1 -0
- package/dist/resolvers/TagGovernanceResolver.js +245 -0
- package/dist/resolvers/TagGovernanceResolver.js.map +1 -0
- package/dist/resolvers/TaskResolver.d.ts +1 -1
- package/dist/resolvers/TaskResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskResolver.js +4 -2
- package/dist/resolvers/TaskResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +2 -1
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +4 -4
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +9 -9
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +4 -4
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts +4 -2
- package/dist/services/TaskOrchestrator.d.ts.map +1 -1
- package/dist/services/TaskOrchestrator.js +16 -12
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/package.json +68 -66
- package/src/__tests__/TagGovernanceResolver.test.ts +255 -0
- package/src/agents/skip-sdk.ts +30 -7
- package/src/auth/exampleNewUserSubClass.ts +1 -1
- package/src/auth/index.ts +2 -2
- package/src/auth/newUsers.ts +2 -2
- package/src/context.ts +3 -3
- package/src/generated/generated.ts +872 -41
- package/src/generic/ResolverBase.ts +28 -21
- package/src/index.ts +9 -9
- package/src/multiTenancy/index.ts +1 -1
- package/src/resolvers/APIKeyResolver.ts +7 -4
- package/src/resolvers/AutotagPipelineResolver.ts +20 -11
- package/src/resolvers/ComponentRegistryResolver.ts +8 -5
- package/src/resolvers/FileResolver.ts +2 -2
- package/src/resolvers/GetDataContextDataResolver.ts +1 -2
- package/src/resolvers/ISAEntityResolver.ts +3 -5
- package/src/resolvers/IntegrationDiscoveryResolver.ts +83 -66
- package/src/resolvers/SyncDataResolver.ts +12 -11
- package/src/resolvers/SyncRolesUsersResolver.ts +23 -19
- package/src/resolvers/TagGovernanceResolver.ts +189 -0
- package/src/resolvers/TaskResolver.ts +5 -3
- package/src/resolvers/TransactionGroupResolver.ts +3 -2
- package/src/rest/EntityCRUDHandler.ts +4 -4
- package/src/rest/RESTEndpointHandler.ts +9 -9
- package/src/rest/ViewOperationsHandler.ts +4 -4
- package/src/services/TaskOrchestrator.ts +18 -13
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Resolver, Query, Mutation, Arg, Ctx, ObjectType, Field, InputType } from "type-graphql";
|
|
2
|
-
import { CompositeKey, LocalCacheManager, Metadata, RunView, UserInfo, LogError } from "@memberjunction/core";
|
|
2
|
+
import { CompositeKey, LocalCacheManager, Metadata, RunView, UserInfo, LogError, IMetadataProvider } from "@memberjunction/core";
|
|
3
|
+
import { GetReadOnlyProvider, GetReadWriteProvider } from "../util.js";
|
|
3
4
|
import { CronExpressionHelper } from "@memberjunction/scheduling-engine";
|
|
4
5
|
import {
|
|
5
6
|
MJCompanyIntegrationEntity,
|
|
@@ -780,7 +781,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
780
781
|
): Promise<DiscoverObjectsOutput> {
|
|
781
782
|
try {
|
|
782
783
|
const user = this.getAuthenticatedUser(ctx);
|
|
783
|
-
const
|
|
784
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
785
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
784
786
|
|
|
785
787
|
// Cast through unknown to bridge duplicate package type declarations
|
|
786
788
|
// (integration-engine resolves its own node_modules copies of core/core-entities)
|
|
@@ -818,7 +820,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
818
820
|
): Promise<ListSourceObjectsOutput> {
|
|
819
821
|
try {
|
|
820
822
|
const user = this.getAuthenticatedUser(ctx);
|
|
821
|
-
const
|
|
823
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
824
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
822
825
|
|
|
823
826
|
// Use the engine cache for already-persisted IntegrationObject
|
|
824
827
|
// rows — single in-memory read instead of a per-call DB roundtrip.
|
|
@@ -918,7 +921,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
918
921
|
): Promise<DiscoverFieldsOutput> {
|
|
919
922
|
try {
|
|
920
923
|
const user = this.getAuthenticatedUser(ctx);
|
|
921
|
-
const
|
|
924
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
925
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
922
926
|
|
|
923
927
|
// Cast through unknown to bridge duplicate package type declarations
|
|
924
928
|
const discoverFields = connector.DiscoverFields.bind(connector) as
|
|
@@ -952,7 +956,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
952
956
|
): Promise<ConnectionTestOutput> {
|
|
953
957
|
try {
|
|
954
958
|
const user = this.getAuthenticatedUser(ctx);
|
|
955
|
-
const
|
|
959
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
960
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
956
961
|
|
|
957
962
|
// Cast through unknown to bridge duplicate package type declarations
|
|
958
963
|
const testConnection = connector.TestConnection.bind(connector) as
|
|
@@ -984,7 +989,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
984
989
|
): Promise<DefaultConfigOutput> {
|
|
985
990
|
try {
|
|
986
991
|
const user = this.getAuthenticatedUser(ctx);
|
|
987
|
-
const {
|
|
992
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
993
|
+
const { connector } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
988
994
|
|
|
989
995
|
const config = connector.GetDefaultConfiguration();
|
|
990
996
|
if (!config) {
|
|
@@ -1032,7 +1038,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1032
1038
|
): Promise<SchemaPreviewOutput> {
|
|
1033
1039
|
try {
|
|
1034
1040
|
const user = this.getAuthenticatedUser(ctx);
|
|
1035
|
-
const
|
|
1041
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
1042
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
1036
1043
|
|
|
1037
1044
|
// Introspect schema from the external system
|
|
1038
1045
|
const introspect = connector.IntrospectSchema.bind(connector) as
|
|
@@ -1059,7 +1066,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1059
1066
|
AdditionalSchemaInfoPath: process.env.RSU_ADDITIONAL_SCHEMA_INFO_PATH ?? 'additionalSchemaInfo.json',
|
|
1060
1067
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
1061
1068
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
1062
|
-
ExistingTables: this.buildExistingTables(targetConfigs),
|
|
1069
|
+
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
1063
1070
|
EntitySettingsForTargets: {}
|
|
1064
1071
|
};
|
|
1065
1072
|
|
|
@@ -1112,7 +1119,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1112
1119
|
): Promise<PreviewDataOutput> {
|
|
1113
1120
|
try {
|
|
1114
1121
|
const user = this.getAuthenticatedUser(ctx);
|
|
1115
|
-
const
|
|
1122
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
1123
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
1116
1124
|
|
|
1117
1125
|
const fetchChanges = connector.FetchChanges.bind(connector) as
|
|
1118
1126
|
(ctx: unknown) => Promise<{ Records: Array<{ ExternalID: string; ObjectType: string; Fields: Record<string, unknown> }>; HasMore: boolean }>;
|
|
@@ -1268,11 +1276,10 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1268
1276
|
|
|
1269
1277
|
/** Builds a lookup of object name → { objectDescription, fields: fieldName → description } from the connector's static metadata. */
|
|
1270
1278
|
/** Build ExistingTableInfo[] from MJ Metadata for tables that already exist in the target schemas. */
|
|
1271
|
-
private buildExistingTables(targetConfigs: TargetTableConfig[]): ExistingTableInfo[] {
|
|
1272
|
-
const md = new Metadata();
|
|
1279
|
+
private buildExistingTables(targetConfigs: TargetTableConfig[], provider: IMetadataProvider): ExistingTableInfo[] {
|
|
1273
1280
|
const result: ExistingTableInfo[] = [];
|
|
1274
1281
|
for (const config of targetConfigs) {
|
|
1275
|
-
const entity =
|
|
1282
|
+
const entity = provider.Entities.find(e =>
|
|
1276
1283
|
e.SchemaName.toLowerCase() === config.SchemaName.toLowerCase() &&
|
|
1277
1284
|
e.BaseTable.toLowerCase() === config.TableName.toLowerCase()
|
|
1278
1285
|
);
|
|
@@ -1597,9 +1604,10 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1597
1604
|
*/
|
|
1598
1605
|
private async resolveConnector(
|
|
1599
1606
|
companyIntegrationID: string,
|
|
1600
|
-
contextUser: UserInfo
|
|
1607
|
+
contextUser: UserInfo,
|
|
1608
|
+
provider: IMetadataProvider
|
|
1601
1609
|
): Promise<{ connector: BaseIntegrationConnector; companyIntegration: MJCompanyIntegrationEntity }> {
|
|
1602
|
-
const md =
|
|
1610
|
+
const md = provider;
|
|
1603
1611
|
|
|
1604
1612
|
// Load the CompanyIntegration record
|
|
1605
1613
|
const companyIntegration = await md.GetEntityObject<MJCompanyIntegrationEntity>(
|
|
@@ -1657,9 +1665,10 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1657
1665
|
*/
|
|
1658
1666
|
private async testConnectionForCI(
|
|
1659
1667
|
companyIntegrationID: string,
|
|
1660
|
-
user: UserInfo
|
|
1668
|
+
user: UserInfo,
|
|
1669
|
+
provider: IMetadataProvider
|
|
1661
1670
|
): Promise<ConnectionTestResult> {
|
|
1662
|
-
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user);
|
|
1671
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
1663
1672
|
const testFn = connector.TestConnection.bind(connector) as
|
|
1664
1673
|
(ci: unknown, u: unknown) => Promise<ConnectionTestResult>;
|
|
1665
1674
|
return testFn(companyIntegration, user);
|
|
@@ -1681,11 +1690,11 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1681
1690
|
*/
|
|
1682
1691
|
private async snapshotCredentialValues(
|
|
1683
1692
|
credentialID: string | undefined,
|
|
1684
|
-
user: UserInfo
|
|
1693
|
+
user: UserInfo,
|
|
1694
|
+
provider: IMetadataProvider
|
|
1685
1695
|
): Promise<string | undefined> {
|
|
1686
1696
|
if (!credentialID) return undefined;
|
|
1687
|
-
const
|
|
1688
|
-
const credential = await md.GetEntityObject<MJCredentialEntity>('MJ: Credentials', user);
|
|
1697
|
+
const credential = await provider.GetEntityObject<MJCredentialEntity>('MJ: Credentials', user);
|
|
1689
1698
|
const loaded = await credential.InnerLoad(CompositeKey.FromID(credentialID));
|
|
1690
1699
|
return loaded ? credential.Values : undefined;
|
|
1691
1700
|
}
|
|
@@ -1699,7 +1708,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1699
1708
|
oldConfiguration: string | undefined,
|
|
1700
1709
|
oldExternalSystemID: string | undefined,
|
|
1701
1710
|
oldCredentialValues: string | undefined,
|
|
1702
|
-
user: UserInfo
|
|
1711
|
+
user: UserInfo,
|
|
1712
|
+
provider: IMetadataProvider
|
|
1703
1713
|
): Promise<void> {
|
|
1704
1714
|
try {
|
|
1705
1715
|
// Revert CI fields
|
|
@@ -1710,8 +1720,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1710
1720
|
|
|
1711
1721
|
// Revert credential values
|
|
1712
1722
|
if (oldCredentialValues !== undefined && ci.CredentialID) {
|
|
1713
|
-
const
|
|
1714
|
-
const credential = await md.GetEntityObject<MJCredentialEntity>('MJ: Credentials', user);
|
|
1723
|
+
const credential = await provider.GetEntityObject<MJCredentialEntity>('MJ: Credentials', user);
|
|
1715
1724
|
const loaded = await credential.InnerLoad(CompositeKey.FromID(ci.CredentialID));
|
|
1716
1725
|
if (loaded) {
|
|
1717
1726
|
credential.Values = oldCredentialValues;
|
|
@@ -1788,7 +1797,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1788
1797
|
): Promise<CreateConnectionOutput> {
|
|
1789
1798
|
try {
|
|
1790
1799
|
const user = this.getAuthenticatedUser(ctx);
|
|
1791
|
-
const md =
|
|
1800
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
1792
1801
|
|
|
1793
1802
|
// 1. Create Credential record with encrypted values
|
|
1794
1803
|
const credential = await md.GetEntityObject<MJCredentialEntity>('MJ: Credentials', user);
|
|
@@ -1824,7 +1833,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1824
1833
|
|
|
1825
1834
|
// 3. Optionally test the connection; rollback on failure
|
|
1826
1835
|
if (testConnection) {
|
|
1827
|
-
const testResult = await this.testConnectionForCI(ci.ID, user);
|
|
1836
|
+
const testResult = await this.testConnectionForCI(ci.ID, user, md);
|
|
1828
1837
|
if (!testResult.Success) {
|
|
1829
1838
|
await this.rollbackCreatedConnection(ci, credential);
|
|
1830
1839
|
return {
|
|
@@ -1870,13 +1879,13 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1870
1879
|
): Promise<MutationResultOutput> {
|
|
1871
1880
|
try {
|
|
1872
1881
|
const user = this.getAuthenticatedUser(ctx);
|
|
1873
|
-
const md =
|
|
1882
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
1874
1883
|
const ci = await md.GetEntityObject<MJCompanyIntegrationEntity>('MJ: Company Integrations', user);
|
|
1875
1884
|
const loaded = await ci.InnerLoad(CompositeKey.FromID(companyIntegrationID));
|
|
1876
1885
|
if (!loaded) return { Success: false, Message: 'CompanyIntegration not found' };
|
|
1877
1886
|
|
|
1878
1887
|
// Snapshot old values for rollback if testConnection is requested
|
|
1879
|
-
const oldCredentialValues = credentialValues ? await this.snapshotCredentialValues(ci.CredentialID, user) : undefined;
|
|
1888
|
+
const oldCredentialValues = credentialValues ? await this.snapshotCredentialValues(ci.CredentialID, user, md) : undefined;
|
|
1880
1889
|
const oldConfiguration = ci.Configuration;
|
|
1881
1890
|
const oldExternalSystemID = ci.ExternalSystemID;
|
|
1882
1891
|
|
|
@@ -1901,9 +1910,9 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1901
1910
|
|
|
1902
1911
|
// Optionally test the connection; revert on failure
|
|
1903
1912
|
if (testConnection) {
|
|
1904
|
-
const testResult = await this.testConnectionForCI(companyIntegrationID, user);
|
|
1913
|
+
const testResult = await this.testConnectionForCI(companyIntegrationID, user, md);
|
|
1905
1914
|
if (!testResult.Success) {
|
|
1906
|
-
await this.revertUpdateConnection(ci, oldConfiguration, oldExternalSystemID, oldCredentialValues, user);
|
|
1915
|
+
await this.revertUpdateConnection(ci, oldConfiguration, oldExternalSystemID, oldCredentialValues, user, md);
|
|
1907
1916
|
return { Success: false, Message: `Connection test failed: ${testResult.Message}. Changes have been reverted.` };
|
|
1908
1917
|
}
|
|
1909
1918
|
return { Success: true, Message: 'Updated and connection test passed' };
|
|
@@ -1926,7 +1935,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1926
1935
|
): Promise<MutationResultOutput> {
|
|
1927
1936
|
try {
|
|
1928
1937
|
const user = this.getAuthenticatedUser(ctx);
|
|
1929
|
-
const md =
|
|
1938
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
1930
1939
|
const ci = await md.GetEntityObject<MJCompanyIntegrationEntity>('MJ: Company Integrations', user);
|
|
1931
1940
|
const loaded = await ci.InnerLoad(CompositeKey.FromID(companyIntegrationID));
|
|
1932
1941
|
if (!loaded) return { Success: false, Message: 'CompanyIntegration not found' };
|
|
@@ -1949,7 +1958,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1949
1958
|
): Promise<MutationResultOutput> {
|
|
1950
1959
|
try {
|
|
1951
1960
|
const user = this.getAuthenticatedUser(ctx);
|
|
1952
|
-
const md =
|
|
1961
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
1953
1962
|
const ci = await md.GetEntityObject<MJCompanyIntegrationEntity>('MJ: Company Integrations', user);
|
|
1954
1963
|
const loaded = await ci.InnerLoad(CompositeKey.FromID(companyIntegrationID));
|
|
1955
1964
|
if (!loaded) return { Success: false, Message: 'CompanyIntegration not found' };
|
|
@@ -1976,7 +1985,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1976
1985
|
): Promise<CreateEntityMapsOutput> {
|
|
1977
1986
|
try {
|
|
1978
1987
|
const user = this.getAuthenticatedUser(ctx);
|
|
1979
|
-
const md =
|
|
1988
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
1980
1989
|
|
|
1981
1990
|
// Batch resolve entity names → IDs using cached Metadata
|
|
1982
1991
|
const namesToResolve = entityMaps.filter(m => m.EntityName && !m.EntityID).map(m => m.EntityName as string);
|
|
@@ -2074,7 +2083,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2074
2083
|
): Promise<ApplySchemaOutput> {
|
|
2075
2084
|
try {
|
|
2076
2085
|
const user = this.getAuthenticatedUser(ctx);
|
|
2077
|
-
const
|
|
2086
|
+
const provider = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2087
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
2078
2088
|
|
|
2079
2089
|
const introspect = connector.IntrospectSchema.bind(connector) as
|
|
2080
2090
|
(ci: unknown, u: unknown) => Promise<SourceSchemaInfo>;
|
|
@@ -2099,7 +2109,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2099
2109
|
AdditionalSchemaInfoPath: process.env.RSU_ADDITIONAL_SCHEMA_INFO_PATH ?? 'additionalSchemaInfo.json',
|
|
2100
2110
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
2101
2111
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
2102
|
-
ExistingTables: this.buildExistingTables(targetConfigs),
|
|
2112
|
+
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
2103
2113
|
EntitySettingsForTargets: {}
|
|
2104
2114
|
};
|
|
2105
2115
|
|
|
@@ -2147,6 +2157,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2147
2157
|
): Promise<ApplySchemaBatchOutput> {
|
|
2148
2158
|
try {
|
|
2149
2159
|
const user = this.getAuthenticatedUser(ctx);
|
|
2160
|
+
const provider = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2150
2161
|
const validatedPlatform = this.validatePlatform(platform);
|
|
2151
2162
|
const pipelineInputs: RSUPipelineInput[] = [];
|
|
2152
2163
|
const itemResults: ApplySchemaBatchItemOutput[] = [];
|
|
@@ -2155,7 +2166,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2155
2166
|
for (const item of items) {
|
|
2156
2167
|
try {
|
|
2157
2168
|
const { schemaOutput, rsuInput } = await this.buildSchemaForConnector(
|
|
2158
|
-
item.CompanyIntegrationID, item.Objects, validatedPlatform, user, skipGitCommit, skipRestart
|
|
2169
|
+
item.CompanyIntegrationID, item.Objects, validatedPlatform, user, skipGitCommit, skipRestart, provider
|
|
2159
2170
|
);
|
|
2160
2171
|
pipelineInputs.push(rsuInput);
|
|
2161
2172
|
itemResults.push({
|
|
@@ -2218,10 +2229,11 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2218
2229
|
): Promise<ApplyAllOutput> {
|
|
2219
2230
|
try {
|
|
2220
2231
|
const user = this.getAuthenticatedUser(ctx);
|
|
2232
|
+
const provider = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2221
2233
|
const validatedPlatform = this.validatePlatform(platform);
|
|
2222
2234
|
|
|
2223
2235
|
// Step 1: Resolve connector and derive schema name
|
|
2224
|
-
const { connector, companyIntegration } = await this.resolveConnector(input.CompanyIntegrationID, user);
|
|
2236
|
+
const { connector, companyIntegration } = await this.resolveConnector(input.CompanyIntegrationID, user, provider);
|
|
2225
2237
|
const schemaName = this.deriveSchemaName(companyIntegration.Integration);
|
|
2226
2238
|
|
|
2227
2239
|
// Step 1b: Ensure IntegrationEngine cache is populated so IntrospectSchema's
|
|
@@ -2310,7 +2322,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2310
2322
|
|
|
2311
2323
|
// Step 3: Build schema and RSU pipeline input
|
|
2312
2324
|
const { schemaOutput, rsuInput } = await this.buildSchemaForConnector(
|
|
2313
|
-
input.CompanyIntegrationID, objects, validatedPlatform, user, skipGitCommit, skipRestart
|
|
2325
|
+
input.CompanyIntegrationID, objects, validatedPlatform, user, skipGitCommit, skipRestart, provider
|
|
2314
2326
|
);
|
|
2315
2327
|
|
|
2316
2328
|
// Step 4: Inject integration post-restart payload into RSU input.
|
|
@@ -2368,9 +2380,9 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2368
2380
|
// If restart happened, this code never executes (process died).
|
|
2369
2381
|
// If skipRestart=true, we can do entity maps now.
|
|
2370
2382
|
if (skipRestart) {
|
|
2371
|
-
await
|
|
2383
|
+
await provider.Refresh();
|
|
2372
2384
|
const entityMapsCreated = await this.createEntityAndFieldMaps(
|
|
2373
|
-
input.CompanyIntegrationID, objects, connector, companyIntegration, schemaName, user,
|
|
2385
|
+
input.CompanyIntegrationID, objects, connector, companyIntegration, schemaName, user, provider,
|
|
2374
2386
|
input.DefaultSyncDirection ?? 'Pull'
|
|
2375
2387
|
);
|
|
2376
2388
|
const createdMapIDs = entityMapsCreated.map(em => em.EntityMapID).filter(Boolean);
|
|
@@ -2394,7 +2406,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2394
2406
|
companyIntegration.Integration,
|
|
2395
2407
|
input.CronExpression,
|
|
2396
2408
|
input.ScheduleTimezone,
|
|
2397
|
-
user
|
|
2409
|
+
user,
|
|
2410
|
+
provider
|
|
2398
2411
|
) ?? undefined;
|
|
2399
2412
|
} catch (schedErr) {
|
|
2400
2413
|
console.warn(`[Integration] Schedule creation failed: ${schedErr}`);
|
|
@@ -2460,14 +2473,14 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2460
2473
|
companyIntegration: MJCompanyIntegrationEntity,
|
|
2461
2474
|
schemaName: string,
|
|
2462
2475
|
user: UserInfo,
|
|
2476
|
+
provider: IMetadataProvider,
|
|
2463
2477
|
defaultSyncDirection: string = 'Pull'
|
|
2464
2478
|
): Promise<ApplyAllEntityMapCreated[]> {
|
|
2465
|
-
const md = new Metadata();
|
|
2466
2479
|
const results: ApplyAllEntityMapCreated[] = [];
|
|
2467
2480
|
|
|
2468
2481
|
for (const obj of objects) {
|
|
2469
2482
|
const entityMapResult = await this.createSingleEntityMap(
|
|
2470
|
-
companyIntegrationID, obj, connector, companyIntegration, schemaName, user,
|
|
2483
|
+
companyIntegrationID, obj, connector, companyIntegration, schemaName, user, provider, defaultSyncDirection
|
|
2471
2484
|
);
|
|
2472
2485
|
if (entityMapResult) {
|
|
2473
2486
|
results.push(entityMapResult);
|
|
@@ -2484,7 +2497,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2484
2497
|
companyIntegration: MJCompanyIntegrationEntity,
|
|
2485
2498
|
schemaName: string,
|
|
2486
2499
|
user: UserInfo,
|
|
2487
|
-
md:
|
|
2500
|
+
md: IMetadataProvider,
|
|
2488
2501
|
defaultSyncDirection: string = 'Pull'
|
|
2489
2502
|
): Promise<ApplyAllEntityMapCreated | null> {
|
|
2490
2503
|
// Find the entity by schema + table name
|
|
@@ -2533,7 +2546,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2533
2546
|
connector: BaseIntegrationConnector,
|
|
2534
2547
|
companyIntegration: MJCompanyIntegrationEntity,
|
|
2535
2548
|
user: UserInfo,
|
|
2536
|
-
md:
|
|
2549
|
+
md: IMetadataProvider
|
|
2537
2550
|
): Promise<number> {
|
|
2538
2551
|
let fieldCount = 0;
|
|
2539
2552
|
try {
|
|
@@ -2609,9 +2622,10 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2609
2622
|
user: UserInfo,
|
|
2610
2623
|
skipGitCommit: boolean,
|
|
2611
2624
|
skipRestart: boolean,
|
|
2625
|
+
provider: IMetadataProvider,
|
|
2612
2626
|
prefetchedSourceSchema?: SourceSchemaInfo
|
|
2613
2627
|
): Promise<{ schemaOutput: SchemaBuilderOutput; rsuInput: RSUPipelineInput }> {
|
|
2614
|
-
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user);
|
|
2628
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
2615
2629
|
|
|
2616
2630
|
// If the caller already ran IntrospectSchema (e.g. IntegrationApplyAllBatch),
|
|
2617
2631
|
// reuse it. The legacy path was running introspect TWICE per apply — once
|
|
@@ -2652,7 +2666,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2652
2666
|
AdditionalSchemaInfoPath: process.env.RSU_ADDITIONAL_SCHEMA_INFO_PATH ?? 'additionalSchemaInfo.json',
|
|
2653
2667
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
2654
2668
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
2655
|
-
ExistingTables: this.buildExistingTables(targetConfigs),
|
|
2669
|
+
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
2656
2670
|
EntitySettingsForTargets: {}
|
|
2657
2671
|
};
|
|
2658
2672
|
|
|
@@ -2866,7 +2880,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2866
2880
|
): Promise<CreateScheduleOutput> {
|
|
2867
2881
|
try {
|
|
2868
2882
|
const user = this.getAuthenticatedUser(ctx);
|
|
2869
|
-
const md =
|
|
2883
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2870
2884
|
const rv = new RunView();
|
|
2871
2885
|
|
|
2872
2886
|
// Find IntegrationSync job type
|
|
@@ -2926,7 +2940,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2926
2940
|
): Promise<MutationResultOutput> {
|
|
2927
2941
|
try {
|
|
2928
2942
|
const user = this.getAuthenticatedUser(ctx);
|
|
2929
|
-
const md =
|
|
2943
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2930
2944
|
const job = await md.GetEntityObject<MJScheduledJobEntity>('MJ: Scheduled Jobs', user);
|
|
2931
2945
|
const loaded = await job.InnerLoad(CompositeKey.FromID(scheduledJobID));
|
|
2932
2946
|
if (!loaded) return { Success: false, Message: 'ScheduledJob not found' };
|
|
@@ -2955,7 +2969,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2955
2969
|
try {
|
|
2956
2970
|
this.getAuthenticatedUser(ctx); // verify caller is authenticated
|
|
2957
2971
|
const sysUser = this.getSystemUser();
|
|
2958
|
-
const md =
|
|
2972
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2959
2973
|
const job = await md.GetEntityObject<MJScheduledJobEntity>('MJ: Scheduled Jobs', sysUser);
|
|
2960
2974
|
const loaded = await job.InnerLoad(CompositeKey.FromID(scheduledJobID));
|
|
2961
2975
|
if (!loaded) return { Success: false, Message: 'ScheduledJob not found' };
|
|
@@ -2980,7 +2994,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
2980
2994
|
try {
|
|
2981
2995
|
this.getAuthenticatedUser(ctx); // verify caller is authenticated
|
|
2982
2996
|
const sysUser = this.getSystemUser(); // use system user for delete operations
|
|
2983
|
-
const md =
|
|
2997
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
2984
2998
|
|
|
2985
2999
|
// Unlink from CI if provided
|
|
2986
3000
|
if (companyIntegrationID) {
|
|
@@ -3034,7 +3048,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3034
3048
|
}
|
|
3035
3049
|
|
|
3036
3050
|
// Now delete job runs + job in a transaction
|
|
3037
|
-
const tg = await
|
|
3051
|
+
const tg = await md.CreateTransactionGroup();
|
|
3038
3052
|
if (jobRunsResult.Success) {
|
|
3039
3053
|
for (const run of jobRunsResult.Results) {
|
|
3040
3054
|
run.TransactionGroup = tg;
|
|
@@ -3163,7 +3177,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3163
3177
|
): Promise<MutationResultOutput> {
|
|
3164
3178
|
try {
|
|
3165
3179
|
const user = this.getAuthenticatedUser(ctx);
|
|
3166
|
-
const md =
|
|
3180
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
3167
3181
|
const errors: string[] = [];
|
|
3168
3182
|
|
|
3169
3183
|
for (const update of updates) {
|
|
@@ -3206,9 +3220,9 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3206
3220
|
try {
|
|
3207
3221
|
this.getAuthenticatedUser(ctx);
|
|
3208
3222
|
const sysUser = this.getSystemUser();
|
|
3209
|
-
const md =
|
|
3223
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
3210
3224
|
const rv = new RunView();
|
|
3211
|
-
const tg = await
|
|
3225
|
+
const tg = await md.CreateTransactionGroup();
|
|
3212
3226
|
const errors: string[] = [];
|
|
3213
3227
|
|
|
3214
3228
|
for (const entityMapID of entityMapIDs) {
|
|
@@ -3328,7 +3342,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3328
3342
|
): Promise<IntegrationStatusOutput> {
|
|
3329
3343
|
try {
|
|
3330
3344
|
const user = this.getAuthenticatedUser(ctx);
|
|
3331
|
-
const md =
|
|
3345
|
+
const md = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
3332
3346
|
const ci = await md.GetEntityObject<MJCompanyIntegrationEntity>('MJ: Company Integrations', user);
|
|
3333
3347
|
const loaded = await ci.InnerLoad(CompositeKey.FromID(companyIntegrationID));
|
|
3334
3348
|
if (!loaded) return { Success: false, Message: 'Not found' };
|
|
@@ -3427,7 +3441,8 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3427
3441
|
): Promise<ConnectorCapabilitiesOutput> {
|
|
3428
3442
|
try {
|
|
3429
3443
|
const user = this.getAuthenticatedUser(ctx);
|
|
3430
|
-
const {
|
|
3444
|
+
const provider = GetReadOnlyProvider(ctx.providers, { allowFallbackToReadWrite: true }) as unknown as IMetadataProvider;
|
|
3445
|
+
const { connector } = await this.resolveConnector(companyIntegrationID, user, provider);
|
|
3431
3446
|
|
|
3432
3447
|
return {
|
|
3433
3448
|
Success: true,
|
|
@@ -3462,6 +3477,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3462
3477
|
): Promise<ApplyAllBatchOutput> {
|
|
3463
3478
|
try {
|
|
3464
3479
|
const user = this.getAuthenticatedUser(ctx);
|
|
3480
|
+
const provider = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
3465
3481
|
const validatedPlatform = this.validatePlatform(platform);
|
|
3466
3482
|
|
|
3467
3483
|
// Bust RunView caches for integration metadata BEFORE Config(true).
|
|
@@ -3478,7 +3494,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3478
3494
|
// Phase 1: Build schema for each connector in parallel
|
|
3479
3495
|
const buildResults = await Promise.allSettled(
|
|
3480
3496
|
input.Connectors.map(async (connInput) => {
|
|
3481
|
-
const { connector, companyIntegration } = await this.resolveConnector(connInput.CompanyIntegrationID, user);
|
|
3497
|
+
const { connector, companyIntegration } = await this.resolveConnector(connInput.CompanyIntegrationID, user, provider);
|
|
3482
3498
|
const schemaName = this.deriveSchemaName(companyIntegration.Integration);
|
|
3483
3499
|
console.log(
|
|
3484
3500
|
`[IntegrationApplyAllBatch] connector=${companyIntegration.Integration} ` +
|
|
@@ -3601,7 +3617,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3601
3617
|
});
|
|
3602
3618
|
|
|
3603
3619
|
const { schemaOutput, rsuInput } = await this.buildSchemaForConnector(
|
|
3604
|
-
connInput.CompanyIntegrationID, objects, validatedPlatform, user, skipGitCommit, skipRestart, sourceSchema
|
|
3620
|
+
connInput.CompanyIntegrationID, objects, validatedPlatform, user, skipGitCommit, skipRestart, provider, sourceSchema
|
|
3605
3621
|
);
|
|
3606
3622
|
|
|
3607
3623
|
// Build per-object field map for pending file
|
|
@@ -3719,10 +3735,10 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3719
3735
|
|
|
3720
3736
|
if (skipRestart) {
|
|
3721
3737
|
// Entity maps, field maps, sync
|
|
3722
|
-
await
|
|
3738
|
+
await provider.Refresh();
|
|
3723
3739
|
const entityMapsCreated = await this.createEntityAndFieldMaps(
|
|
3724
3740
|
build.connInput.CompanyIntegrationID, build.objects, build.connector,
|
|
3725
|
-
build.companyIntegration, build.schemaName, user,
|
|
3741
|
+
build.companyIntegration, build.schemaName, user, provider,
|
|
3726
3742
|
build.connInput.DefaultSyncDirection ?? 'Pull'
|
|
3727
3743
|
);
|
|
3728
3744
|
connResult.EntityMapsCreated = entityMapsCreated;
|
|
@@ -3747,7 +3763,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3747
3763
|
if (build.connInput.CronExpression) {
|
|
3748
3764
|
const scheduleResult = await this.createScheduleForConnector(
|
|
3749
3765
|
build.connInput.CompanyIntegrationID, integrationName,
|
|
3750
|
-
build.connInput.CronExpression, build.connInput.ScheduleTimezone, user
|
|
3766
|
+
build.connInput.CronExpression, build.connInput.ScheduleTimezone, user, provider
|
|
3751
3767
|
);
|
|
3752
3768
|
if (scheduleResult) connResult.ScheduledJobID = scheduleResult;
|
|
3753
3769
|
}
|
|
@@ -3793,10 +3809,11 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3793
3809
|
integrationName: string,
|
|
3794
3810
|
cronExpression: string,
|
|
3795
3811
|
timezone: string | undefined,
|
|
3796
|
-
user: UserInfo
|
|
3812
|
+
user: UserInfo,
|
|
3813
|
+
provider: IMetadataProvider
|
|
3797
3814
|
): Promise<string | null> {
|
|
3798
3815
|
try {
|
|
3799
|
-
const md =
|
|
3816
|
+
const md = provider;
|
|
3800
3817
|
const rv = new RunView();
|
|
3801
3818
|
|
|
3802
3819
|
// Find IntegrationSync job type
|
|
@@ -3857,7 +3874,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3857
3874
|
try {
|
|
3858
3875
|
this.getAuthenticatedUser(ctx); // verify caller is authenticated
|
|
3859
3876
|
const sysUser = this.getSystemUser(); // use system user for cascade delete
|
|
3860
|
-
const md =
|
|
3877
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
3861
3878
|
const rv = new RunView();
|
|
3862
3879
|
|
|
3863
3880
|
// Step 1: Load CompanyIntegration
|
|
@@ -3866,7 +3883,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3866
3883
|
if (!ciLoaded) return { Success: false, Message: 'CompanyIntegration not found' };
|
|
3867
3884
|
|
|
3868
3885
|
// Cascade delete in FK-safe order using TransactionGroup
|
|
3869
|
-
const tg = await
|
|
3886
|
+
const tg = await md.CreateTransactionGroup();
|
|
3870
3887
|
let fieldMapsDeleted = 0;
|
|
3871
3888
|
let entityMapsDeleted = 0;
|
|
3872
3889
|
let schedulesDeleted = 0;
|
|
@@ -4046,9 +4063,9 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
4046
4063
|
try {
|
|
4047
4064
|
const user = this.getAuthenticatedUser(ctx);
|
|
4048
4065
|
const validatedPlatform = this.validatePlatform(platform);
|
|
4049
|
-
const
|
|
4066
|
+
const md = GetReadWriteProvider(ctx.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider;
|
|
4067
|
+
const { connector, companyIntegration } = await this.resolveConnector(companyIntegrationID, user, md);
|
|
4050
4068
|
const schemaName = this.deriveSchemaName(companyIntegration.Integration);
|
|
4051
|
-
const md = new Metadata();
|
|
4052
4069
|
const rv = new RunView();
|
|
4053
4070
|
|
|
4054
4071
|
// Step 1: Get existing entity maps for this CompanyIntegration
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } from 'type-graphql';
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
|
-
import { BaseEntity, CompositeKey, DatabaseProviderBase, EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
3
|
+
import { BaseEntity, CompositeKey, DatabaseProviderBase, EntityDeleteOptions, EntitySaveOptions, IMetadataProvider, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
5
6
|
import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
6
7
|
import { MJDatasetItemEntity } from '@memberjunction/core-entities';
|
|
7
8
|
|
|
@@ -110,9 +111,9 @@ export class SyncDataResolver {
|
|
|
110
111
|
@Arg('items', () => [ActionItemInputType] ) items: ActionItemInputType[],
|
|
111
112
|
@Ctx() context: AppContext
|
|
112
113
|
) {
|
|
113
|
-
try {
|
|
114
|
-
// iterate through the items
|
|
115
|
-
const md = new Metadata();
|
|
114
|
+
try {
|
|
115
|
+
// iterate through the items
|
|
116
|
+
const md = (GetReadWriteProvider(context.providers, { allowFallbackToReadOnly: true }) as unknown as IMetadataProvider) ?? (new Metadata() as unknown as IMetadataProvider);
|
|
116
117
|
const results: ActionItemOutputType[] = [];
|
|
117
118
|
for (const item of items) {
|
|
118
119
|
results.push(await this.SyncSingleItem(item, context, md, context.userPayload));
|
|
@@ -160,7 +161,7 @@ export class SyncDataResolver {
|
|
|
160
161
|
return false; // didn't find any
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md:
|
|
164
|
+
protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: IMetadataProvider, userPayload: UserPayload): Promise<ActionItemOutputType> {
|
|
164
165
|
const result = new ActionItemOutputType();
|
|
165
166
|
result.AlternateKey = item.AlternateKey;
|
|
166
167
|
result.PrimaryKey = item.PrimaryKey;
|
|
@@ -192,7 +193,7 @@ export class SyncDataResolver {
|
|
|
192
193
|
await this.SyncSingleItemDelete(entityObject, pk, ak, result, userPayload);
|
|
193
194
|
break;
|
|
194
195
|
case SyncDataActionType.DeleteWithFilter:
|
|
195
|
-
await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord, userPayload);
|
|
196
|
+
await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord, userPayload, md);
|
|
196
197
|
break;
|
|
197
198
|
default:
|
|
198
199
|
throw new Error('Invalid SyncDataActionType');
|
|
@@ -211,7 +212,7 @@ export class SyncDataResolver {
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
|
|
214
|
-
protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo, userPayload: UserPayload) {
|
|
215
|
+
protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo, userPayload: UserPayload, providerOverride?: IMetadataProvider) {
|
|
215
216
|
try {
|
|
216
217
|
// Run the view to find matching records, then delete them all atomically —
|
|
217
218
|
// any single failure rolls back the entire batch so the dataset stays consistent.
|
|
@@ -233,7 +234,7 @@ export class SyncDataResolver {
|
|
|
233
234
|
return;
|
|
234
235
|
}
|
|
235
236
|
|
|
236
|
-
const provider = Metadata.Provider as DatabaseProviderBase;
|
|
237
|
+
const provider = (providerOverride ?? Metadata.Provider) as unknown as DatabaseProviderBase;
|
|
237
238
|
await provider.BeginTransaction();
|
|
238
239
|
try {
|
|
239
240
|
for (const entityObject of data.Results) {
|
|
@@ -254,11 +255,11 @@ export class SyncDataResolver {
|
|
|
254
255
|
}
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
protected async LoadFromAlternateKey(entityName: string, alternateKey: CompositeKey, user: UserInfo): Promise<BaseEntity> {
|
|
258
|
+
protected async LoadFromAlternateKey(entityName: string, alternateKey: CompositeKey, user: UserInfo, provider?: IMetadataProvider): Promise<BaseEntity> {
|
|
258
259
|
try {
|
|
259
|
-
// no primary key provided, attempt to look up the primary key based on the
|
|
260
|
+
// no primary key provided, attempt to look up the primary key based on the
|
|
260
261
|
const rv = new RunView();
|
|
261
|
-
const md = new Metadata();
|
|
262
|
+
const md = provider ?? new Metadata();
|
|
262
263
|
const entity = md.EntityByName(entityName);
|
|
263
264
|
const r = await rv.RunView<BaseEntity>({
|
|
264
265
|
EntityName: entityName,
|