@memberjunction/server 2.94.0 → 2.96.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/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +4 -0
- package/dist/context.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +5 -4
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.d.ts +8 -3
- package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
- package/dist/resolvers/AskSkipResolver.js +241 -25
- package/dist/resolvers/AskSkipResolver.js.map +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts +2 -2
- package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/CreateQueryResolver.js +25 -17
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +2 -2
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +6 -5
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +4 -4
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +6 -5
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +10 -11
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +5 -6
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +2 -2
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.js +3 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +3 -3
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +8 -7
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +4 -3
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +19 -14
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/ReportResolver.d.ts +2 -2
- package/dist/resolvers/ReportResolver.d.ts.map +1 -1
- package/dist/resolvers/ReportResolver.js +8 -6
- package/dist/resolvers/ReportResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +3 -7
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +8 -5
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +3 -7
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +10 -8
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts +2 -4
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +5 -4
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +7 -7
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.d.ts +3 -4
- package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +10 -68
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +3 -4
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/package.json +39 -39
- package/src/config.ts +2 -0
- package/src/context.ts +5 -0
- package/src/resolvers/ActionResolver.ts +5 -4
- package/src/resolvers/AskSkipResolver.ts +300 -29
- package/src/resolvers/CreateQueryResolver.ts +28 -17
- package/src/resolvers/DatasetResolver.ts +5 -4
- package/src/resolvers/EntityRecordNameResolver.ts +8 -6
- package/src/resolvers/FileCategoryResolver.ts +9 -10
- package/src/resolvers/FileResolver.ts +6 -7
- package/src/resolvers/GetDataContextDataResolver.ts +2 -2
- package/src/resolvers/GetDataResolver.ts +2 -2
- package/src/resolvers/InfoResolver.ts +1 -1
- package/src/resolvers/MergeRecordsResolver.ts +7 -6
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +3 -2
- package/src/resolvers/QueryResolver.ts +22 -15
- package/src/resolvers/ReportResolver.ts +9 -6
- package/src/resolvers/RunAIAgentResolver.ts +12 -4
- package/src/resolvers/RunAIPromptResolver.ts +12 -8
- package/src/resolvers/RunTemplateResolver.ts +5 -5
- package/src/resolvers/SqlLoggingConfigResolver.ts +7 -6
- package/src/resolvers/UserFavoriteResolver.ts +8 -67
- package/src/resolvers/UserViewResolver.ts +3 -3
|
@@ -16,16 +16,15 @@ export class FileResolver extends FileCategoryResolverBase {
|
|
|
16
16
|
) {
|
|
17
17
|
const key = new CompositeKey();
|
|
18
18
|
key.LoadFromSingleKeyValuePair('ID', ID);
|
|
19
|
-
const
|
|
19
|
+
const p = GetReadWriteProvider(providers);
|
|
20
20
|
|
|
21
|
-
if (!(await this.BeforeDelete(
|
|
21
|
+
if (!(await this.BeforeDelete(p, key))) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const md = new Metadata();
|
|
26
25
|
const user = this.GetUserFromPayload(userPayload);
|
|
27
|
-
const fileEntity = await
|
|
28
|
-
const fileCategoryEntity = await
|
|
26
|
+
const fileEntity = await p.GetEntityObject<FileEntity>('Files', user);
|
|
27
|
+
const fileCategoryEntity = await p.GetEntityObject<FileCategoryEntity>('File Categories', user);
|
|
29
28
|
|
|
30
29
|
fileEntity.CheckPermissions(EntityPermissionType.Update, true);
|
|
31
30
|
fileCategoryEntity.CheckPermissions(EntityPermissionType.Delete, true);
|
|
@@ -34,7 +33,7 @@ export class FileResolver extends FileCategoryResolverBase {
|
|
|
34
33
|
const returnValue = fileCategoryEntity.GetAll();
|
|
35
34
|
|
|
36
35
|
// Any files using the deleted category fall back to its parent
|
|
37
|
-
await
|
|
36
|
+
await p.BeginTransaction();
|
|
38
37
|
try {
|
|
39
38
|
// SHOULD USE BaseEntity for each of these records to ensure object model
|
|
40
39
|
// is used everywhere - new code below. The below is SLOWER than a single
|
|
@@ -60,20 +59,20 @@ export class FileResolver extends FileCategoryResolverBase {
|
|
|
60
59
|
// iterate through each of the files in filesResult.Results
|
|
61
60
|
// and update the CategoryID to fileCategoryEntity.ParentID
|
|
62
61
|
for (const file of filesResult.Results) {
|
|
63
|
-
const fileEntity = await
|
|
62
|
+
const fileEntity = await p.GetEntityObject<FileEntity>('Files', user);
|
|
64
63
|
await fileEntity.Load(file.ID);
|
|
65
64
|
fileEntity.CategoryID = fileCategoryEntity.ParentID;
|
|
66
65
|
await fileEntity.Save();
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
await fileCategoryEntity.Delete(options);
|
|
70
|
-
await
|
|
69
|
+
await p.CommitTransaction();
|
|
71
70
|
} catch (error) {
|
|
72
|
-
await
|
|
71
|
+
await p.RollbackTransaction();
|
|
73
72
|
throw error;
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
await this.AfterDelete(
|
|
75
|
+
await this.AfterDelete(p, key); // fire event
|
|
77
76
|
return returnValue;
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -51,14 +51,13 @@ export class FileResolver extends FileResolverBase {
|
|
|
51
51
|
@Ctx() context: AppContext,
|
|
52
52
|
@PubSub() pubSub: PubSubEngine
|
|
53
53
|
) {
|
|
54
|
-
|
|
54
|
+
// Check to see if there's already an object with that name
|
|
55
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
55
56
|
const user = this.GetUserFromPayload(context.userPayload);
|
|
56
|
-
const fileEntity = await
|
|
57
|
-
const providerEntity = await
|
|
57
|
+
const fileEntity = await provider.GetEntityObject<FileEntity>('Files', user);
|
|
58
|
+
const providerEntity = await provider.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
58
59
|
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
59
60
|
|
|
60
|
-
// Check to see if there's already an object with that name
|
|
61
|
-
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
62
61
|
const [sameName] = await this.findBy(
|
|
63
62
|
provider,
|
|
64
63
|
'Files',
|
|
@@ -108,7 +107,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
108
107
|
@PubSub() pubSub: PubSubEngine
|
|
109
108
|
) {
|
|
110
109
|
// if the name is changing, rename the target object as well
|
|
111
|
-
const md =
|
|
110
|
+
const md = GetReadOnlyProvider(context.providers);
|
|
112
111
|
const user = this.GetUserFromPayload(context.userPayload);
|
|
113
112
|
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
114
113
|
fileEntity.CheckPermissions(EntityPermissionType.Update, true);
|
|
@@ -136,7 +135,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
136
135
|
@Ctx() context: AppContext,
|
|
137
136
|
@PubSub() pubSub: PubSubEngine
|
|
138
137
|
) {
|
|
139
|
-
const md =
|
|
138
|
+
const md = GetReadOnlyProvider(context.providers);
|
|
140
139
|
const userInfo = this.GetUserFromPayload(context.userPayload);
|
|
141
140
|
|
|
142
141
|
const fileEntity = await md.GetEntityObject<FileEntity>('Files', userInfo);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, ObjectType, Query } from "type-graphql";
|
|
2
2
|
import { AppContext } from "../types.js";
|
|
3
3
|
import { DataContext } from "@memberjunction/data-context";
|
|
4
|
-
import { GetReadOnlyDataSource } from "../util.js";
|
|
4
|
+
import { GetReadOnlyDataSource, GetReadOnlyProvider } from "../util.js";
|
|
5
5
|
import { Metadata } from "@memberjunction/core";
|
|
6
6
|
import { DataContextItemEntity } from "@memberjunction/core-entities";
|
|
7
7
|
|
|
@@ -53,7 +53,7 @@ export class GetDataContextDataResolver {
|
|
|
53
53
|
const ds = GetReadOnlyDataSource(appCtx.dataSources, {
|
|
54
54
|
allowFallbackToReadWrite: true,
|
|
55
55
|
})
|
|
56
|
-
const md =
|
|
56
|
+
const md = GetReadOnlyProvider(appCtx.providers, {allowFallbackToReadWrite: true});
|
|
57
57
|
const dciData = await md.GetEntityObject<DataContextItemEntity>("Data Context Items", appCtx.userPayload.userRecord);
|
|
58
58
|
if (await dciData.Load(DataContextItemID)) {
|
|
59
59
|
const dci = DataContext.CreateDataContextItem(); // use class factory to get whatever lowest level sub-class is registered
|
|
@@ -3,7 +3,7 @@ import { AppContext } from '../types.js';
|
|
|
3
3
|
import { LogError, LogStatus, Metadata } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
-
import { GetReadOnlyDataSource } from '../util.js';
|
|
6
|
+
import { GetReadOnlyDataSource, GetReadOnlyProvider } from '../util.js';
|
|
7
7
|
import sql from 'mssql';
|
|
8
8
|
|
|
9
9
|
@InputType()
|
|
@@ -169,7 +169,7 @@ export class GetDataResolver {
|
|
|
169
169
|
@Ctx() context: AppContext
|
|
170
170
|
): Promise<SimpleEntityResultType> {
|
|
171
171
|
try {
|
|
172
|
-
const md =
|
|
172
|
+
const md = GetReadOnlyProvider(context.providers);
|
|
173
173
|
const result = md.Entities.map((e) => {
|
|
174
174
|
return {
|
|
175
175
|
ID: e.ID,
|
|
@@ -3,6 +3,7 @@ import { Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, PubSub, PubSubEn
|
|
|
3
3
|
import { AppContext } from '../types.js';
|
|
4
4
|
import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
+
import { GetReadOnlyProvider, GetReadWriteProvider } from '../util.js';
|
|
6
7
|
|
|
7
8
|
@ObjectType()
|
|
8
9
|
export class EntityDependencyResult {
|
|
@@ -21,11 +22,11 @@ export class EntityDependencyResolver {
|
|
|
21
22
|
@Query(() => [EntityDependencyResult])
|
|
22
23
|
async GetEntityDependencies(
|
|
23
24
|
@Arg('entityName', () => String) entityName: string,
|
|
24
|
-
@Ctx() { dataSource, userPayload }: AppContext,
|
|
25
|
+
@Ctx() { dataSource, userPayload, providers }: AppContext,
|
|
25
26
|
@PubSub() pubSub: PubSubEngine
|
|
26
27
|
) {
|
|
27
28
|
try {
|
|
28
|
-
const md =
|
|
29
|
+
const md = GetReadOnlyProvider(providers);
|
|
29
30
|
return md.GetEntityDependencies(entityName);
|
|
30
31
|
} catch (err) {
|
|
31
32
|
LogError(err);
|
|
@@ -57,11 +58,11 @@ export class RecordDependencyResolver {
|
|
|
57
58
|
async GetRecordDependencies(
|
|
58
59
|
@Arg('entityName', () => String) entityName: string,
|
|
59
60
|
@Arg('CompositeKey', () => CompositeKeyInputType) ckInput: CompositeKeyInputType,
|
|
60
|
-
@Ctx() { dataSource, userPayload }: AppContext,
|
|
61
|
+
@Ctx() { dataSource, userPayload, providers }: AppContext,
|
|
61
62
|
@PubSub() pubSub: PubSubEngine
|
|
62
63
|
) {
|
|
63
64
|
try {
|
|
64
|
-
const md =
|
|
65
|
+
const md = GetReadOnlyProvider(providers);
|
|
65
66
|
const ck = new CompositeKey(ckInput.KeyValuePairs);
|
|
66
67
|
const result = await md.GetRecordDependencies(entityName, ck);
|
|
67
68
|
|
|
@@ -165,11 +166,11 @@ export class RecordMergeResolver {
|
|
|
165
166
|
@Mutation(() => RecordMergeResult)
|
|
166
167
|
async MergeRecords(
|
|
167
168
|
@Arg('request', () => RecordMergeRequest) request: RecordMergeRequest,
|
|
168
|
-
@Ctx() { dataSource, userPayload }: AppContext,
|
|
169
|
+
@Ctx() { dataSource, userPayload, providers }: AppContext,
|
|
169
170
|
@PubSub() pubSub: PubSubEngine
|
|
170
171
|
) {
|
|
171
172
|
try {
|
|
172
|
-
const md =
|
|
173
|
+
const md = GetReadWriteProvider(providers);
|
|
173
174
|
const options = {};
|
|
174
175
|
const result = await md.MergeRecords(request, userPayload.userRecord, options);
|
|
175
176
|
return result;
|
|
@@ -14,6 +14,7 @@ import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
|
14
14
|
import { LoadMistralEmbedding } from '@memberjunction/ai-mistral';
|
|
15
15
|
import { LoadPineconeVectorDB } from '@memberjunction/ai-vectors-pinecone';
|
|
16
16
|
import { CompositeKeyInputType, CompositeKeyOutputType, KeyValuePairOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
17
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
17
18
|
LoadMistralEmbedding();
|
|
18
19
|
LoadPineconeVectorDB();
|
|
19
20
|
|
|
@@ -75,10 +76,10 @@ export class PotentialDuplicateResponseType extends PotentialDuplicateResponse {
|
|
|
75
76
|
export class DuplicateRecordResolver {
|
|
76
77
|
@Query(() => PotentialDuplicateResponseType)
|
|
77
78
|
async GetRecordDuplicates(
|
|
78
|
-
@Ctx() { dataSource, userPayload }: AppContext,
|
|
79
|
+
@Ctx() { dataSource, userPayload, providers }: AppContext,
|
|
79
80
|
@Arg('params') params: PotentialDuplicateRequestType
|
|
80
81
|
): Promise<PotentialDuplicateResponseType> {
|
|
81
|
-
const md =
|
|
82
|
+
const md = GetReadOnlyProvider(providers);
|
|
82
83
|
|
|
83
84
|
const user = UserCache.Instance.Users.find((u) => u.Email.trim().toLowerCase() === userPayload.email.trim().toLowerCase());
|
|
84
85
|
if (!user) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Arg, Ctx, ObjectType, Query, Resolver, Field, Int } from 'type-graphql';
|
|
2
|
-
import { RunQuery, QueryInfo } from '@memberjunction/core';
|
|
2
|
+
import { RunQuery, QueryInfo, IRunQueryProvider, IMetadataProvider } from '@memberjunction/core';
|
|
3
3
|
import { AppContext } from '../types.js';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { GraphQLJSONObject } from 'graphql-type-json';
|
|
6
6
|
import { Metadata } from '@memberjunction/core';
|
|
7
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
7
8
|
|
|
8
9
|
@ObjectType()
|
|
9
10
|
export class RunQueryResultType {
|
|
@@ -43,9 +44,7 @@ export class RunQueryResultType {
|
|
|
43
44
|
|
|
44
45
|
@Resolver()
|
|
45
46
|
export class RunQueryResolver {
|
|
46
|
-
private async findQuery(QueryID: string, QueryName?: string, CategoryID?: string, CategoryPath?: string, refreshMetadataIfNotFound: boolean = false): Promise<QueryInfo | null> {
|
|
47
|
-
const md = new Metadata();
|
|
48
|
-
|
|
47
|
+
private async findQuery(md: IMetadataProvider, QueryID: string, QueryName?: string, CategoryID?: string, CategoryPath?: string, refreshMetadataIfNotFound: boolean = false): Promise<QueryInfo | null> {
|
|
49
48
|
// Filter queries based on provided criteria
|
|
50
49
|
const queries = md.Queries.filter(q => {
|
|
51
50
|
if (QueryID) {
|
|
@@ -67,7 +66,7 @@ export class RunQueryResolver {
|
|
|
67
66
|
if (refreshMetadataIfNotFound) {
|
|
68
67
|
// If we didn't find the query, refresh metadata and try again
|
|
69
68
|
await md.Refresh();
|
|
70
|
-
return this.findQuery(QueryID, QueryName, CategoryID, CategoryPath, false); // change the refresh flag to false so we don't loop infinitely
|
|
69
|
+
return this.findQuery(md, QueryID, QueryName, CategoryID, CategoryPath, false); // change the refresh flag to false so we don't loop infinitely
|
|
71
70
|
}
|
|
72
71
|
else {
|
|
73
72
|
return null; // No query found and not refreshing metadata
|
|
@@ -87,9 +86,11 @@ export class RunQueryResolver {
|
|
|
87
86
|
@Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
|
|
88
87
|
@Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
|
|
89
88
|
@Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string): Promise<RunQueryResultType> {
|
|
90
|
-
const
|
|
89
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
|
|
90
|
+
const md = provider as unknown as IMetadataProvider;
|
|
91
|
+
const rq = new RunQuery(provider as unknown as IRunQueryProvider);
|
|
91
92
|
console.log('GetQueryData called with:', { QueryID, Parameters, MaxRows, StartRow, ForceAuditLog, AuditLogDescription });
|
|
92
|
-
const result = await
|
|
93
|
+
const result = await rq.RunQuery(
|
|
93
94
|
{
|
|
94
95
|
QueryID: QueryID,
|
|
95
96
|
CategoryID: CategoryID,
|
|
@@ -111,7 +112,7 @@ export class RunQueryResolver {
|
|
|
111
112
|
let queryName = result.QueryName;
|
|
112
113
|
if (!queryName) {
|
|
113
114
|
try {
|
|
114
|
-
const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryPath, true);
|
|
115
|
+
const queryInfo = await this.findQuery(md, QueryID, undefined, CategoryID, CategoryPath, true);
|
|
115
116
|
if (queryInfo) {
|
|
116
117
|
queryName = queryInfo.Name;
|
|
117
118
|
}
|
|
@@ -145,8 +146,9 @@ export class RunQueryResolver {
|
|
|
145
146
|
@Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
|
|
146
147
|
@Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
|
|
147
148
|
@Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string): Promise<RunQueryResultType> {
|
|
148
|
-
const
|
|
149
|
-
const
|
|
149
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
|
|
150
|
+
const rq = new RunQuery(provider as unknown as IRunQueryProvider);
|
|
151
|
+
const result = await rq.RunQuery(
|
|
150
152
|
{
|
|
151
153
|
QueryName: QueryName,
|
|
152
154
|
CategoryID: CategoryID,
|
|
@@ -185,8 +187,11 @@ export class RunQueryResolver {
|
|
|
185
187
|
@Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
|
|
186
188
|
@Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
|
|
187
189
|
@Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string): Promise<RunQueryResultType> {
|
|
188
|
-
const
|
|
189
|
-
const
|
|
190
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
|
|
191
|
+
const md = provider as unknown as IMetadataProvider;
|
|
192
|
+
const rq = new RunQuery(provider as unknown as IRunQueryProvider);
|
|
193
|
+
|
|
194
|
+
const result = await rq.RunQuery(
|
|
190
195
|
{
|
|
191
196
|
QueryID: QueryID,
|
|
192
197
|
CategoryID: CategoryID,
|
|
@@ -203,7 +208,7 @@ export class RunQueryResolver {
|
|
|
203
208
|
let queryName = result.QueryName;
|
|
204
209
|
if (!queryName) {
|
|
205
210
|
try {
|
|
206
|
-
const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryPath, true);
|
|
211
|
+
const queryInfo = await this.findQuery(md, QueryID, undefined, CategoryID, CategoryPath, true);
|
|
207
212
|
if (queryInfo) {
|
|
208
213
|
queryName = queryInfo.Name;
|
|
209
214
|
}
|
|
@@ -238,8 +243,10 @@ export class RunQueryResolver {
|
|
|
238
243
|
@Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
|
|
239
244
|
@Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
|
|
240
245
|
@Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string): Promise<RunQueryResultType> {
|
|
241
|
-
const
|
|
242
|
-
const
|
|
246
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
|
|
247
|
+
const rq = new RunQuery(provider as unknown as IRunQueryProvider);
|
|
248
|
+
|
|
249
|
+
const result = await rq.RunQuery(
|
|
243
250
|
{
|
|
244
251
|
QueryName: QueryName,
|
|
245
252
|
CategoryID: CategoryID,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntitySaveOptions, Metadata, RunReport } from '@memberjunction/core';
|
|
1
|
+
import { EntitySaveOptions, IRunReportProvider, Metadata, RunReport } from '@memberjunction/core';
|
|
2
2
|
import { Arg, Ctx, Field, Int, Mutation, ObjectType, Query, Resolver } from 'type-graphql';
|
|
3
3
|
import { AppContext } from '../types.js';
|
|
4
4
|
import { ConversationDetailEntity, ReportEntity } from '@memberjunction/core-entities';
|
|
@@ -7,6 +7,7 @@ import { DataContext } from '@memberjunction/data-context';
|
|
|
7
7
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import mssql from 'mssql';
|
|
10
|
+
import { GetReadOnlyProvider, GetReadWriteProvider } from '../util.js';
|
|
10
11
|
|
|
11
12
|
@ObjectType()
|
|
12
13
|
export class RunReportResultType {
|
|
@@ -47,9 +48,11 @@ export class CreateReportResultType {
|
|
|
47
48
|
@Resolver(RunReportResultType)
|
|
48
49
|
export class ReportResolverExtended {
|
|
49
50
|
@Query(() => RunReportResultType)
|
|
50
|
-
async GetReportData(@Arg('ReportID', () => String) ReportID: string, @Ctx()
|
|
51
|
-
const
|
|
52
|
-
const
|
|
51
|
+
async GetReportData(@Arg('ReportID', () => String) ReportID: string, @Ctx() context: AppContext): Promise<RunReportResultType> {
|
|
52
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
|
|
53
|
+
const rp = new RunReport(provider as unknown as IRunReportProvider);
|
|
54
|
+
|
|
55
|
+
const result = await rp.RunReport({ ReportID: ReportID });
|
|
53
56
|
return {
|
|
54
57
|
ReportID: ReportID,
|
|
55
58
|
Success: result.Success,
|
|
@@ -66,10 +69,10 @@ export class ReportResolverExtended {
|
|
|
66
69
|
@Mutation(() => CreateReportResultType)
|
|
67
70
|
async CreateReportFromConversationDetailID(
|
|
68
71
|
@Arg('ConversationDetailID', () => String) ConversationDetailID: string,
|
|
69
|
-
@Ctx() { dataSource, userPayload }: AppContext
|
|
72
|
+
@Ctx() { dataSource, userPayload, providers }: AppContext
|
|
70
73
|
): Promise<CreateReportResultType> {
|
|
71
74
|
try {
|
|
72
|
-
const md =
|
|
75
|
+
const md = GetReadWriteProvider(providers);
|
|
73
76
|
|
|
74
77
|
const u = UserCache.Users.find((u) => u.Email?.trim().toLowerCase() === userPayload?.email?.trim().toLowerCase());
|
|
75
78
|
if (!u) throw new Error('Unable to find user');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Resolver, Mutation, Query, Arg, Ctx, ObjectType, Field, PubSub, PubSubEngine, Subscription, Root, ResolverFilterData, ID } from 'type-graphql';
|
|
2
|
-
import { UserPayload } from '../types.js';
|
|
3
|
-
import { LogError, LogStatus } from '@memberjunction/core';
|
|
2
|
+
import { AppContext, UserPayload } from '../types.js';
|
|
3
|
+
import { DatabaseProviderBase, LogError, LogStatus } from '@memberjunction/core';
|
|
4
4
|
import { AIAgentEntityExtended } from '@memberjunction/core-entities';
|
|
5
5
|
import { AgentRunner } from '@memberjunction/ai-agents';
|
|
6
6
|
import { ExecuteAgentResult } from '@memberjunction/ai-core-plus';
|
|
@@ -8,6 +8,7 @@ import { AIEngine } from '@memberjunction/aiengine';
|
|
|
8
8
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
9
9
|
import { PUSH_STATUS_UPDATES_TOPIC } from '../generic/PushStatusResolver.js';
|
|
10
10
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
11
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
11
12
|
|
|
12
13
|
@ObjectType()
|
|
13
14
|
export class AIAgentRunResult {
|
|
@@ -304,6 +305,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
304
305
|
* @private
|
|
305
306
|
*/
|
|
306
307
|
private async executeAIAgent(
|
|
308
|
+
p: DatabaseProviderBase,
|
|
307
309
|
agentId: string,
|
|
308
310
|
userPayload: UserPayload,
|
|
309
311
|
messagesJson: string,
|
|
@@ -339,6 +341,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
339
341
|
// Validate agent
|
|
340
342
|
const agentEntity = await this.validateAgent(agentId, currentUser);
|
|
341
343
|
|
|
344
|
+
// @jordanfanapour IMPORTANT TO-DO for various engine classes (via base engine class) and here for AI Agent Runner and for AI Prompt Runner, need to be able to pass in a IMetadataProvider for it to use
|
|
345
|
+
// for multi-user server environments like this one
|
|
342
346
|
// Create AI agent runner
|
|
343
347
|
const agentRunner = new AgentRunner();
|
|
344
348
|
|
|
@@ -453,7 +457,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
453
457
|
@Mutation(() => AIAgentRunResult)
|
|
454
458
|
async RunAIAgent(
|
|
455
459
|
@Arg('agentId') agentId: string,
|
|
456
|
-
@Ctx() { userPayload }:
|
|
460
|
+
@Ctx() { userPayload, providers }: AppContext,
|
|
457
461
|
@Arg('messages') messagesJson: string,
|
|
458
462
|
@Arg('sessionId') sessionId: string,
|
|
459
463
|
@PubSub() pubSub: PubSubEngine,
|
|
@@ -463,7 +467,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
463
467
|
@Arg('autoPopulateLastRunPayload', { nullable: true }) autoPopulateLastRunPayload?: boolean,
|
|
464
468
|
@Arg('configurationId', { nullable: true }) configurationId?: string
|
|
465
469
|
): Promise<AIAgentRunResult> {
|
|
470
|
+
const p = GetReadWriteProvider(providers);
|
|
466
471
|
return this.executeAIAgent(
|
|
472
|
+
p,
|
|
467
473
|
agentId,
|
|
468
474
|
userPayload,
|
|
469
475
|
messagesJson,
|
|
@@ -485,7 +491,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
485
491
|
@Query(() => AIAgentRunResult)
|
|
486
492
|
async RunAIAgentSystemUser(
|
|
487
493
|
@Arg('agentId') agentId: string,
|
|
488
|
-
@Ctx() { userPayload }:
|
|
494
|
+
@Ctx() { userPayload, providers }: AppContext,
|
|
489
495
|
@Arg('messages') messagesJson: string,
|
|
490
496
|
@Arg('sessionId') sessionId: string,
|
|
491
497
|
@PubSub() pubSub: PubSubEngine,
|
|
@@ -495,7 +501,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
495
501
|
@Arg('autoPopulateLastRunPayload', { nullable: true }) autoPopulateLastRunPayload?: boolean,
|
|
496
502
|
@Arg('configurationId', { nullable: true }) configurationId?: string
|
|
497
503
|
): Promise<AIAgentRunResult> {
|
|
504
|
+
const p = GetReadWriteProvider(providers);
|
|
498
505
|
return this.executeAIAgent(
|
|
506
|
+
p,
|
|
499
507
|
agentId,
|
|
500
508
|
userPayload,
|
|
501
509
|
messagesJson,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Resolver, Mutation, Query, Arg, Ctx, ObjectType, Field, Int } from 'type-graphql';
|
|
2
|
-
import { UserPayload } from '../types.js';
|
|
3
|
-
import { LogError, LogStatus, Metadata } from '@memberjunction/core';
|
|
2
|
+
import { AppContext, UserPayload } from '../types.js';
|
|
3
|
+
import { DatabaseProviderBase, LogError, LogStatus, Metadata } from '@memberjunction/core';
|
|
4
4
|
import { AIPromptEntityExtended, AIModelEntityExtended } from '@memberjunction/core-entities';
|
|
5
5
|
import { AIPromptRunner } from '@memberjunction/ai-prompts';
|
|
6
6
|
import { AIPromptParams } from '@memberjunction/ai-core-plus';
|
|
@@ -9,6 +9,7 @@ import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
|
9
9
|
import { AIEngine } from '@memberjunction/aiengine';
|
|
10
10
|
import { ChatParams, ChatMessage, ChatMessageRole, GetAIAPIKey, BaseLLM } from '@memberjunction/ai';
|
|
11
11
|
import { MJGlobal } from '@memberjunction/global';
|
|
12
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
12
13
|
|
|
13
14
|
@ObjectType()
|
|
14
15
|
export class AIPromptRunResult {
|
|
@@ -87,6 +88,7 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
87
88
|
* @private
|
|
88
89
|
*/
|
|
89
90
|
private async executeAIPrompt(
|
|
91
|
+
p: DatabaseProviderBase,
|
|
90
92
|
promptId: string,
|
|
91
93
|
userPayload: UserPayload,
|
|
92
94
|
data?: string,
|
|
@@ -152,11 +154,9 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
152
154
|
executionTimeMs: Date.now() - startTime
|
|
153
155
|
};
|
|
154
156
|
}
|
|
155
|
-
|
|
156
|
-
const md = new Metadata();
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
// Load the AI prompt entity
|
|
159
|
-
const promptEntity = await
|
|
159
|
+
const promptEntity = await p.GetEntityObject<AIPromptEntityExtended>('AI Prompts', currentUser);
|
|
160
160
|
await promptEntity.Load(promptId);
|
|
161
161
|
|
|
162
162
|
if (!promptEntity.IsSaved) {
|
|
@@ -283,7 +283,7 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
283
283
|
@Mutation(() => AIPromptRunResult)
|
|
284
284
|
async RunAIPrompt(
|
|
285
285
|
@Arg('promptId') promptId: string,
|
|
286
|
-
@Ctx() { userPayload }:
|
|
286
|
+
@Ctx() { userPayload, providers }: AppContext,
|
|
287
287
|
@Arg('data', { nullable: true }) data?: string,
|
|
288
288
|
@Arg('overrideModelId', { nullable: true }) overrideModelId?: string,
|
|
289
289
|
@Arg('overrideVendorId', { nullable: true }) overrideVendorId?: string,
|
|
@@ -305,7 +305,9 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
305
305
|
@Arg('rerunFromPromptRunID', { nullable: true }) rerunFromPromptRunID?: string,
|
|
306
306
|
@Arg('systemPromptOverride', { nullable: true }) systemPromptOverride?: string
|
|
307
307
|
): Promise<AIPromptRunResult> {
|
|
308
|
+
const p = GetReadWriteProvider(providers);
|
|
308
309
|
return this.executeAIPrompt(
|
|
310
|
+
p,
|
|
309
311
|
promptId,
|
|
310
312
|
userPayload,
|
|
311
313
|
data,
|
|
@@ -339,7 +341,7 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
339
341
|
@Query(() => AIPromptRunResult)
|
|
340
342
|
async RunAIPromptSystemUser(
|
|
341
343
|
@Arg('promptId') promptId: string,
|
|
342
|
-
@Ctx() { userPayload }:
|
|
344
|
+
@Ctx() { userPayload, providers }: AppContext,
|
|
343
345
|
@Arg('data', { nullable: true }) data?: string,
|
|
344
346
|
@Arg('overrideModelId', { nullable: true }) overrideModelId?: string,
|
|
345
347
|
@Arg('overrideVendorId', { nullable: true }) overrideVendorId?: string,
|
|
@@ -361,7 +363,9 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
361
363
|
@Arg('rerunFromPromptRunID', { nullable: true }) rerunFromPromptRunID?: string,
|
|
362
364
|
@Arg('systemPromptOverride', { nullable: true }) systemPromptOverride?: string
|
|
363
365
|
): Promise<AIPromptRunResult> {
|
|
366
|
+
const p = GetReadWriteProvider(providers);
|
|
364
367
|
return this.executeAIPrompt(
|
|
368
|
+
p,
|
|
365
369
|
promptId,
|
|
366
370
|
userPayload,
|
|
367
371
|
data,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
|
|
2
|
-
import { UserPayload } from '../types.js';
|
|
2
|
+
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
|
|
4
4
|
import { TemplateContentEntity } from '@memberjunction/core-entities';
|
|
5
5
|
import { TemplateEngineServer } from '@memberjunction/templates';
|
|
6
6
|
import { TemplateEntityExtended } from '@memberjunction/templates-base-types';
|
|
7
7
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
8
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
8
9
|
|
|
9
10
|
@ObjectType()
|
|
10
11
|
export class TemplateRunResult {
|
|
@@ -26,7 +27,7 @@ export class RunTemplateResolver extends ResolverBase {
|
|
|
26
27
|
@Mutation(() => TemplateRunResult)
|
|
27
28
|
async RunTemplate(
|
|
28
29
|
@Arg('templateId') templateId: string,
|
|
29
|
-
@Ctx() { userPayload }:
|
|
30
|
+
@Ctx() { userPayload, providers }: AppContext,
|
|
30
31
|
@Arg('contextData', { nullable: true }) contextData?: string
|
|
31
32
|
): Promise<TemplateRunResult> {
|
|
32
33
|
const startTime = Date.now();
|
|
@@ -58,10 +59,9 @@ export class RunTemplateResolver extends ResolverBase {
|
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
const
|
|
62
|
-
|
|
62
|
+
const p = GetReadWriteProvider(providers);
|
|
63
63
|
// Load the template entity
|
|
64
|
-
const templateEntity = await
|
|
64
|
+
const templateEntity = await p.GetEntityObject<TemplateEntityExtended>('Templates', currentUser);
|
|
65
65
|
await templateEntity.Load(templateId);
|
|
66
66
|
|
|
67
67
|
if (!templateEntity.IsSaved) {
|
|
@@ -8,6 +8,7 @@ import * as path from 'path';
|
|
|
8
8
|
import * as fs from 'fs/promises';
|
|
9
9
|
import { loadConfig } from '../config.js';
|
|
10
10
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
11
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Configuration options for SQL logging sessions.
|
|
@@ -279,7 +280,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
279
280
|
async sqlLoggingConfig(@Ctx() context: AppContext): Promise<SqlLoggingConfig> {
|
|
280
281
|
await this.checkOwnerAccess(context);
|
|
281
282
|
const config = await loadConfig();
|
|
282
|
-
const provider =
|
|
283
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
283
284
|
const activeSessions = provider.GetActiveSqlLoggingSessions();
|
|
284
285
|
|
|
285
286
|
return {
|
|
@@ -334,7 +335,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
334
335
|
@Query(() => [SqlLoggingSession])
|
|
335
336
|
async activeSqlLoggingSessions(@Ctx() context: AppContext): Promise<SqlLoggingSession[]> {
|
|
336
337
|
await this.checkOwnerAccess(context);
|
|
337
|
-
const provider =
|
|
338
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
338
339
|
const sessions = provider.GetActiveSqlLoggingSessions();
|
|
339
340
|
|
|
340
341
|
return sessions.map(session => ({
|
|
@@ -399,7 +400,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
399
400
|
}
|
|
400
401
|
|
|
401
402
|
// Check max active sessions
|
|
402
|
-
const provider =
|
|
403
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
403
404
|
const activeSessions = provider.GetActiveSqlLoggingSessions();
|
|
404
405
|
if (activeSessions.length >= (config.sqlLogging.maxActiveSessions ?? 5)) {
|
|
405
406
|
throw new Error(`Maximum number of active SQL logging sessions (${config.sqlLogging.maxActiveSessions}) reached`);
|
|
@@ -480,7 +481,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
480
481
|
@Ctx() context: AppContext
|
|
481
482
|
): Promise<boolean> {
|
|
482
483
|
await this.checkOwnerAccess(context);
|
|
483
|
-
const provider =
|
|
484
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
484
485
|
|
|
485
486
|
// Get the actual session from the private map to call dispose
|
|
486
487
|
const sessionMap = (provider as any)._sqlLoggingSessions as Map<string, any>;
|
|
@@ -517,7 +518,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
517
518
|
@Mutation(() => Boolean)
|
|
518
519
|
async stopAllSqlLogging(@Ctx() context: AppContext): Promise<boolean> {
|
|
519
520
|
await this.checkOwnerAccess(context);
|
|
520
|
-
const provider =
|
|
521
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
521
522
|
await provider.DisposeAllSqlLoggingSessions();
|
|
522
523
|
return true;
|
|
523
524
|
}
|
|
@@ -607,7 +608,7 @@ export class SqlLoggingConfigResolver extends ResolverBase {
|
|
|
607
608
|
}
|
|
608
609
|
|
|
609
610
|
// Find the session
|
|
610
|
-
const provider =
|
|
611
|
+
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true}) as SQLServerDataProvider;
|
|
611
612
|
const sessions = provider.GetActiveSqlLoggingSessions();
|
|
612
613
|
const session = sessions.find(s => s.id === sessionId);
|
|
613
614
|
|