@memberjunction/server 4.4.0 → 5.0.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-agent.js +9 -9
- package/dist/agents/skip-agent.js.map +1 -1
- package/dist/apolloServer/TransactionPlugin.d.ts +4 -0
- package/dist/apolloServer/TransactionPlugin.d.ts.map +1 -0
- package/dist/apolloServer/TransactionPlugin.js +46 -0
- package/dist/apolloServer/TransactionPlugin.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/__tests__/backward-compatibility.test.d.ts +2 -0
- package/dist/auth/__tests__/backward-compatibility.test.d.ts.map +1 -0
- package/dist/auth/__tests__/backward-compatibility.test.js +135 -0
- package/dist/auth/__tests__/backward-compatibility.test.js.map +1 -0
- package/dist/auth/exampleNewUserSubClass.d.ts +2 -2
- package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/newUsers.d.ts +2 -2
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +6 -6
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts +2 -2
- package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js +3 -3
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
- package/dist/generated/generated.d.ts +10724 -10721
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +48710 -48698
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/DeleteOptionsInput.d.ts +12 -2
- package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
- package/dist/generic/DeleteOptionsInput.js +12 -2
- package/dist/generic/DeleteOptionsInput.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +6 -6
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.js +3 -3
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.d.ts +123 -0
- package/dist/resolvers/AskSkipResolver.d.ts.map +1 -0
- package/dist/resolvers/AskSkipResolver.js +1788 -0
- package/dist/resolvers/AskSkipResolver.js.map +1 -0
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts +3 -3
- package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/CreateQueryResolver.js +19 -19
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/EntityResolver.js +1 -1
- package/dist/resolvers/EntityResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +4 -4
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.js +20 -20
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/ISAEntityResolver.d.ts +22 -1
- package/dist/resolvers/ISAEntityResolver.d.ts.map +1 -1
- package/dist/resolvers/ISAEntityResolver.js +77 -1
- package/dist/resolvers/ISAEntityResolver.js.map +1 -1
- package/dist/resolvers/ReportResolver.js +3 -3
- package/dist/resolvers/ReportResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +3 -3
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +1 -1
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +2 -2
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +1 -1
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +9 -9
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +10 -10
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +2 -2
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserResolver.js +8 -8
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.js +5 -5
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +1 -1
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/scheduler/LearningCycleScheduler.d.ts +4 -0
- package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -0
- package/dist/scheduler/LearningCycleScheduler.js +4 -0
- package/dist/scheduler/LearningCycleScheduler.js.map +1 -0
- package/dist/services/TaskOrchestrator.d.ts +1 -1
- package/dist/services/TaskOrchestrator.js +5 -5
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/package.json +52 -52
- package/src/agents/skip-agent.ts +9 -9
- package/src/auth/APIKeyScopeAuth.ts +5 -5
- package/src/auth/exampleNewUserSubClass.ts +2 -2
- package/src/auth/index.ts +3 -3
- package/src/auth/newUsers.ts +9 -9
- package/src/entitySubclasses/entityPermissions.server.ts +3 -3
- package/src/generated/generated.ts +31186 -31177
- package/src/generic/DeleteOptionsInput.ts +12 -2
- package/src/generic/ResolverBase.ts +7 -7
- package/src/generic/RunViewResolver.ts +3 -3
- package/src/resolvers/APIKeyResolver.ts +2 -2
- package/src/resolvers/ComponentRegistryResolver.ts +9 -9
- package/src/resolvers/CreateQueryResolver.ts +18 -18
- package/src/resolvers/EntityResolver.ts +1 -1
- package/src/resolvers/FileCategoryResolver.ts +5 -5
- package/src/resolvers/FileResolver.ts +27 -27
- package/src/resolvers/GetDataContextDataResolver.ts +2 -2
- package/src/resolvers/ISAEntityResolver.ts +77 -1
- package/src/resolvers/ReportResolver.ts +4 -4
- package/src/resolvers/RunAIAgentResolver.ts +7 -7
- package/src/resolvers/RunAIPromptResolver.ts +1 -1
- package/src/resolvers/RunTemplateResolver.ts +4 -4
- package/src/resolvers/SyncDataResolver.ts +3 -3
- package/src/resolvers/SyncRolesUsersResolver.ts +26 -26
- package/src/resolvers/UserFavoriteResolver.ts +2 -2
- package/src/resolvers/UserResolver.ts +8 -8
- package/src/resolvers/UserViewResolver.ts +6 -6
- package/src/rest/ViewOperationsHandler.ts +1 -1
- package/src/services/TaskOrchestrator.ts +31 -31
|
@@ -20,10 +20,27 @@ export class ISAChildEntityResult {
|
|
|
20
20
|
ErrorMessage?: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Result type for the IS-A child entities discovery query (plural).
|
|
25
|
+
* Returns all child entity type names that have records matching the given
|
|
26
|
+
* parent entity's primary key. Used for overlapping subtype parents.
|
|
27
|
+
*/
|
|
28
|
+
@ObjectType()
|
|
29
|
+
export class ISAChildEntitiesResult {
|
|
30
|
+
@Field(() => Boolean)
|
|
31
|
+
Success: boolean;
|
|
32
|
+
|
|
33
|
+
@Field(() => [String], { nullable: true })
|
|
34
|
+
ChildEntityNames?: string[];
|
|
35
|
+
|
|
36
|
+
@Field(() => String, { nullable: true })
|
|
37
|
+
ErrorMessage?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
23
40
|
/**
|
|
24
41
|
* Resolver for IS-A entity hierarchy discovery.
|
|
25
42
|
*
|
|
26
|
-
* Provides
|
|
43
|
+
* Provides GraphQL endpoints for client-side code to discover child entity
|
|
27
44
|
* records in an IS-A hierarchy. This enables bidirectional chain construction
|
|
28
45
|
* where a loaded entity discovers its more-derived child type.
|
|
29
46
|
*/
|
|
@@ -91,6 +108,65 @@ export class ISAEntityResolver {
|
|
|
91
108
|
};
|
|
92
109
|
}
|
|
93
110
|
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Discovers ALL IS-A child entities that have records with the given primary
|
|
114
|
+
* key value. Used for overlapping subtype parents (AllowMultipleSubtypes = true)
|
|
115
|
+
* where multiple children can coexist. The server executes a single UNION ALL
|
|
116
|
+
* query across all child entity tables for maximum efficiency.
|
|
117
|
+
*
|
|
118
|
+
* @param EntityName The parent entity name to check children for
|
|
119
|
+
* @param RecordID The primary key value to search for in child tables
|
|
120
|
+
* @returns Array of child entity names found (empty if none)
|
|
121
|
+
*/
|
|
122
|
+
@Query(() => ISAChildEntitiesResult)
|
|
123
|
+
async FindISAChildEntities(
|
|
124
|
+
@Arg('EntityName', () => String) EntityName: string,
|
|
125
|
+
@Arg('RecordID', () => String) RecordID: string,
|
|
126
|
+
@Ctx() { providers, userPayload }: AppContext
|
|
127
|
+
): Promise<ISAChildEntitiesResult> {
|
|
128
|
+
try {
|
|
129
|
+
const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
|
|
130
|
+
const md = new Metadata();
|
|
131
|
+
const entityInfo = md.Entities.find(e => e.Name === EntityName);
|
|
132
|
+
|
|
133
|
+
if (!entityInfo) {
|
|
134
|
+
return {
|
|
135
|
+
Success: false,
|
|
136
|
+
ErrorMessage: `Entity '${EntityName}' not found`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!entityInfo.IsParentType) {
|
|
141
|
+
return { Success: true, ChildEntityNames: [] };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const entityProvider = provider as unknown as IEntityDataProvider;
|
|
145
|
+
if (!entityProvider.FindISAChildEntities) {
|
|
146
|
+
return {
|
|
147
|
+
Success: false,
|
|
148
|
+
ErrorMessage: 'Provider does not support FindISAChildEntities'
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const results = await entityProvider.FindISAChildEntities(
|
|
153
|
+
entityInfo,
|
|
154
|
+
RecordID,
|
|
155
|
+
userPayload?.userRecord
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
Success: true,
|
|
160
|
+
ChildEntityNames: results.map(r => r.ChildEntityName)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
return {
|
|
165
|
+
Success: false,
|
|
166
|
+
ErrorMessage: e instanceof Error ? e.message : String(e)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
94
170
|
}
|
|
95
171
|
|
|
96
172
|
export default ISAEntityResolver;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
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
|
-
import {
|
|
4
|
+
import { MJConversationDetailEntity, MJReportEntity } from '@memberjunction/core-entities';
|
|
5
5
|
import { SkipAPIAnalysisCompleteResponse } from '@memberjunction/skip-types';
|
|
6
6
|
import { DataContext } from '@memberjunction/data-context';
|
|
7
7
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
@@ -84,10 +84,10 @@ export class ReportResolverExtended extends ResolverBase {
|
|
|
84
84
|
const u = UserCache.Users.find((u) => u.Email?.trim().toLowerCase() === userPayload?.email?.trim().toLowerCase());
|
|
85
85
|
if (!u) throw new Error('Unable to find user');
|
|
86
86
|
|
|
87
|
-
const cde = md.Entities.find((e) => e.Name === 'Conversation Details');
|
|
87
|
+
const cde = md.Entities.find((e) => e.Name === 'MJ: Conversation Details');
|
|
88
88
|
if (!cde) throw new Error('Unable to find Conversation Details Entity metadata');
|
|
89
89
|
|
|
90
|
-
const cd = md.Entities.find((e) => e.Name === 'Conversations');
|
|
90
|
+
const cd = md.Entities.find((e) => e.Name === 'MJ: Conversations');
|
|
91
91
|
if (!cd) throw new Error('Unable to find Conversations Entity metadata');
|
|
92
92
|
|
|
93
93
|
const sql = `SELECT
|
|
@@ -106,7 +106,7 @@ export class ReportResolverExtended extends ResolverBase {
|
|
|
106
106
|
if (!result || !result.recordset || result.recordset.length === 0) throw new Error('Unable to retrieve converation details');
|
|
107
107
|
const skipData = <SkipAPIAnalysisCompleteResponse>JSON.parse(result.recordset[0].Message);
|
|
108
108
|
|
|
109
|
-
const report = await md.GetEntityObject<
|
|
109
|
+
const report = await md.GetEntityObject<MJReportEntity>('MJ: Reports', u);
|
|
110
110
|
report.NewRecord();
|
|
111
111
|
// support the legacy report title as old conversation details had a reportTitle property
|
|
112
112
|
// but the new SkipData object has a title property, so favor the title property
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Resolver, Mutation, Query, Arg, Ctx, ObjectType, Field, PubSub, PubSubEngine, Subscription, Root, ResolverFilterData, ID, Int } from 'type-graphql';
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { DatabaseProviderBase, LogError, LogStatus, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
|
-
import {
|
|
4
|
+
import { MJConversationDetailEntity, MJConversationDetailAttachmentEntity } from '@memberjunction/core-entities';
|
|
5
5
|
import { AgentRunner } from '@memberjunction/ai-agents';
|
|
6
6
|
import { AIAgentEntityExtended, AIAgentRunEntityExtended, ExecuteAgentResult, ConversationUtility, AttachmentData } from '@memberjunction/ai-core-plus';
|
|
7
7
|
import { AIEngine } from '@memberjunction/aiengine';
|
|
@@ -646,8 +646,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
646
646
|
const agentName = agent?.Name || 'Agent';
|
|
647
647
|
|
|
648
648
|
// Load conversation detail to get conversation info
|
|
649
|
-
const detail = await md.GetEntityObject<
|
|
650
|
-
'Conversation Details',
|
|
649
|
+
const detail = await md.GetEntityObject<MJConversationDetailEntity>(
|
|
650
|
+
'MJ: Conversation Details',
|
|
651
651
|
contextUser
|
|
652
652
|
);
|
|
653
653
|
if (!(await detail.Load(conversationDetailId))) {
|
|
@@ -815,8 +815,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
815
815
|
const attachmentService = getAttachmentService();
|
|
816
816
|
|
|
817
817
|
// Load the current conversation detail to get the conversation ID
|
|
818
|
-
const currentDetail = await md.GetEntityObject<
|
|
819
|
-
'Conversation Details',
|
|
818
|
+
const currentDetail = await md.GetEntityObject<MJConversationDetailEntity>(
|
|
819
|
+
'MJ: Conversation Details',
|
|
820
820
|
contextUser
|
|
821
821
|
);
|
|
822
822
|
if (!await currentDetail.Load(conversationDetailId)) {
|
|
@@ -826,8 +826,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
826
826
|
const conversationId = currentDetail.ConversationID;
|
|
827
827
|
|
|
828
828
|
// Load recent conversation details (messages) for this conversation
|
|
829
|
-
const detailsResult = await rv.RunView<
|
|
830
|
-
EntityName: 'Conversation Details',
|
|
829
|
+
const detailsResult = await rv.RunView<MJConversationDetailEntity>({
|
|
830
|
+
EntityName: 'MJ: Conversation Details',
|
|
831
831
|
ExtraFilter: `ConversationID='${conversationId}'`,
|
|
832
832
|
OrderBy: '__mj_CreatedAt DESC',
|
|
833
833
|
MaxRows: maxMessages,
|
|
@@ -156,7 +156,7 @@ export class RunAIPromptResolver extends ResolverBase {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// Load the AI prompt entity
|
|
159
|
-
const promptEntity = await p.GetEntityObject<AIPromptEntityExtended>('AI Prompts', currentUser);
|
|
159
|
+
const promptEntity = await p.GetEntityObject<AIPromptEntityExtended>('MJ: AI Prompts', currentUser);
|
|
160
160
|
await promptEntity.Load(promptId);
|
|
161
161
|
|
|
162
162
|
if (!promptEntity.IsSaved) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
|
|
4
|
-
import {
|
|
4
|
+
import { MJTemplateContentEntity, TemplateEntityExtended } from '@memberjunction/core-entities';
|
|
5
5
|
import { TemplateEngineServer } from '@memberjunction/templates';
|
|
6
6
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
7
7
|
import { GetReadWriteProvider } from '../util.js';
|
|
@@ -63,7 +63,7 @@ export class RunTemplateResolver extends ResolverBase {
|
|
|
63
63
|
|
|
64
64
|
const p = GetReadWriteProvider(providers);
|
|
65
65
|
// Load the template entity
|
|
66
|
-
const templateEntity = await p.GetEntityObject<TemplateEntityExtended>('Templates', currentUser);
|
|
66
|
+
const templateEntity = await p.GetEntityObject<TemplateEntityExtended>('MJ: Templates', currentUser);
|
|
67
67
|
await templateEntity.Load(templateId);
|
|
68
68
|
|
|
69
69
|
if (!templateEntity.IsSaved) {
|
|
@@ -76,8 +76,8 @@ export class RunTemplateResolver extends ResolverBase {
|
|
|
76
76
|
|
|
77
77
|
// Load template content (get the first/highest priority content)
|
|
78
78
|
const rv = new RunView();
|
|
79
|
-
const templateContentResult = await rv.RunView<
|
|
80
|
-
EntityName: 'Template Contents',
|
|
79
|
+
const templateContentResult = await rv.RunView<MJTemplateContentEntity>({
|
|
80
|
+
EntityName: 'MJ: Template Contents',
|
|
81
81
|
ExtraFilter: `TemplateID = '${templateId}'`,
|
|
82
82
|
OrderBy: 'Priority ASC',
|
|
83
83
|
MaxRows: 1,
|
|
@@ -3,7 +3,7 @@ import { AppContext, UserPayload } from '../types.js';
|
|
|
3
3
|
import { BaseEntity, CompositeKey, EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
6
|
-
import {
|
|
6
|
+
import { MJDatasetItemEntity } from '@memberjunction/core-entities';
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -134,8 +134,8 @@ export class SyncDataResolver {
|
|
|
134
134
|
protected async GetLowercaseMetadataEntitiesList(user: UserInfo, forceRefresh: boolean = false): Promise<string[]> {
|
|
135
135
|
if (forceRefresh || __metadata_DatasetItems.length === 0) {
|
|
136
136
|
const rv = new RunView(); // cache this, veyr simple - should use an engine for this stuff later
|
|
137
|
-
const result = await rv.RunView<
|
|
138
|
-
EntityName: "Dataset Items",
|
|
137
|
+
const result = await rv.RunView<MJDatasetItemEntity>({
|
|
138
|
+
EntityName: "MJ: Dataset Items",
|
|
139
139
|
ExtraFilter: "Dataset = 'MJ_Metadata'",
|
|
140
140
|
}, user)
|
|
141
141
|
if (result && result.Success) {
|
|
@@ -2,7 +2,7 @@ import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } fr
|
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
|
-
import {
|
|
5
|
+
import { MJRoleEntity, MJUserEntity, MJUserRoleEntity } from '@memberjunction/core-entities';
|
|
6
6
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
7
7
|
|
|
8
8
|
@ObjectType()
|
|
@@ -124,8 +124,8 @@ export class SyncRolesAndUsersResolver {
|
|
|
124
124
|
// we iterate through the provided roles and we remove roles that are not in the input and add roles that are new
|
|
125
125
|
// and update roles that already exist
|
|
126
126
|
const rv = new RunView();
|
|
127
|
-
const result = await rv.RunView<
|
|
128
|
-
EntityName: "Roles",
|
|
127
|
+
const result = await rv.RunView<MJRoleEntity>({
|
|
128
|
+
EntityName: "MJ: Roles",
|
|
129
129
|
ResultType: 'entity_object'
|
|
130
130
|
}, context.userPayload.userRecord);
|
|
131
131
|
|
|
@@ -145,7 +145,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
protected async UpdateExistingRoles(currentRoles:
|
|
148
|
+
protected async UpdateExistingRoles(currentRoles: MJRoleEntity[], futureRoles: RoleInputType[], userPayload: UserPayload): Promise<SyncRolesAndUsersResultType> {
|
|
149
149
|
// go through the future roles and update any that are in the current roles
|
|
150
150
|
const md = new Metadata();
|
|
151
151
|
let ok: boolean = true;
|
|
@@ -160,14 +160,14 @@ export class SyncRolesAndUsersResolver {
|
|
|
160
160
|
return { Success: ok };
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
protected async AddNewRoles(currentRoles:
|
|
163
|
+
protected async AddNewRoles(currentRoles: MJRoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
164
164
|
// go through the future roles and add any that are not in the current roles
|
|
165
165
|
const md = new Metadata();
|
|
166
166
|
let ok: boolean = true;
|
|
167
167
|
|
|
168
168
|
for (const add of futureRoles) {
|
|
169
169
|
if (!currentRoles.find(r => r.Name.trim().toLowerCase() === add.Name.trim().toLowerCase())) {
|
|
170
|
-
const role = await md.GetEntityObject<
|
|
170
|
+
const role = await md.GetEntityObject<MJRoleEntity>("MJ: Roles", user);
|
|
171
171
|
role.Name = add.Name;
|
|
172
172
|
role.Description = add.Description;
|
|
173
173
|
ok = ok && await role.Save();
|
|
@@ -177,7 +177,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
protected async DeleteRemovedRoles(currentRoles:
|
|
180
|
+
protected async DeleteRemovedRoles(currentRoles: MJRoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
181
181
|
const rv = new RunView();
|
|
182
182
|
let ok: boolean = true;
|
|
183
183
|
|
|
@@ -199,12 +199,12 @@ export class SyncRolesAndUsersResolver {
|
|
|
199
199
|
return this.StandardRoles.find(r => r.toLowerCase() === roleName.toLowerCase()) !== undefined;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
protected async DeleteSingleRole(role:
|
|
202
|
+
protected async DeleteSingleRole(role: MJRoleEntity, rv: RunView, user: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
203
203
|
// first, remove all the UserRole records that match this role
|
|
204
204
|
let ok: boolean = true;
|
|
205
205
|
|
|
206
|
-
const r2 = await rv.RunView<
|
|
207
|
-
EntityName: "User Roles",
|
|
206
|
+
const r2 = await rv.RunView<MJUserRoleEntity>({
|
|
207
|
+
EntityName: "MJ: User Roles",
|
|
208
208
|
ExtraFilter: "RoleID = '" + role.ID + "'",
|
|
209
209
|
ResultType: 'entity_object'
|
|
210
210
|
}, user);
|
|
@@ -232,8 +232,8 @@ export class SyncRolesAndUsersResolver {
|
|
|
232
232
|
// first, we sync up the users and then the user roles.
|
|
233
233
|
// for syncing users we first remove users that are no longer in the input, then we add new users and update existing users
|
|
234
234
|
const rv = new RunView();
|
|
235
|
-
const result = await rv.RunView<
|
|
236
|
-
EntityName: "Users",
|
|
235
|
+
const result = await rv.RunView<MJUserEntity>({
|
|
236
|
+
EntityName: "MJ: Users",
|
|
237
237
|
ResultType: 'entity_object'
|
|
238
238
|
}, context.userPayload.userRecord);
|
|
239
239
|
if (result && result.Success) {
|
|
@@ -257,7 +257,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
protected async UpdateExistingUsers(currentUsers:
|
|
260
|
+
protected async UpdateExistingUsers(currentUsers: MJUserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
|
|
261
261
|
// go through the future users and update any that are in the current users
|
|
262
262
|
let ok: boolean = true;
|
|
263
263
|
|
|
@@ -274,7 +274,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
274
274
|
}
|
|
275
275
|
return ok;
|
|
276
276
|
}
|
|
277
|
-
protected async AddNewUsers(currentUsers:
|
|
277
|
+
protected async AddNewUsers(currentUsers: MJUserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
|
|
278
278
|
// add users that are not in the current users
|
|
279
279
|
const md = new Metadata();
|
|
280
280
|
let ok: boolean = true;
|
|
@@ -287,7 +287,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
287
287
|
ok = ok && await match.Save();
|
|
288
288
|
}
|
|
289
289
|
else {
|
|
290
|
-
const user = await md.GetEntityObject<
|
|
290
|
+
const user = await md.GetEntityObject<MJUserEntity>("MJ: Users", userPayload.userRecord);
|
|
291
291
|
user.Name = add.Name;
|
|
292
292
|
user.Type = add.Type;
|
|
293
293
|
user.Email = add.Email;
|
|
@@ -302,7 +302,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
302
302
|
return ok;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
protected async DeleteRemovedUsers(currentUsers:
|
|
305
|
+
protected async DeleteRemovedUsers(currentUsers: MJUserEntity[], futureUsers: UserInputType[], u: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
306
306
|
// remove users that are not in the future users
|
|
307
307
|
const rv = new RunView();
|
|
308
308
|
const md = new Metadata();
|
|
@@ -319,12 +319,12 @@ export class SyncRolesAndUsersResolver {
|
|
|
319
319
|
return ok;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
protected async DeleteSingleUser(user:
|
|
322
|
+
protected async DeleteSingleUser(user: MJUserEntity, rv: RunView, u: UserInfo, userPayload: UserPayload): Promise<boolean> {
|
|
323
323
|
// first, remove all the UserRole records that match this user
|
|
324
324
|
let ok: boolean = true;
|
|
325
325
|
|
|
326
|
-
const r2 = await rv.RunView<
|
|
327
|
-
EntityName: "User Roles",
|
|
326
|
+
const r2 = await rv.RunView<MJUserRoleEntity>({
|
|
327
|
+
EntityName: "MJ: User Roles",
|
|
328
328
|
ExtraFilter: "UserID = '" + user.ID + "'",
|
|
329
329
|
ResultType: 'entity_object'
|
|
330
330
|
}, u);
|
|
@@ -349,16 +349,16 @@ export class SyncRolesAndUsersResolver {
|
|
|
349
349
|
const rv = new RunView();
|
|
350
350
|
const md = new Metadata();
|
|
351
351
|
|
|
352
|
-
const p1 = rv.RunView<
|
|
353
|
-
EntityName: "Users",
|
|
352
|
+
const p1 = rv.RunView<MJUserEntity>({
|
|
353
|
+
EntityName: "MJ: Users",
|
|
354
354
|
ResultType: 'entity_object'
|
|
355
355
|
}, u);
|
|
356
|
-
const p2 = rv.RunView<
|
|
357
|
-
EntityName: "Roles",
|
|
356
|
+
const p2 = rv.RunView<MJRoleEntity>({
|
|
357
|
+
EntityName: "MJ: Roles",
|
|
358
358
|
ResultType: 'entity_object'
|
|
359
359
|
}, u);
|
|
360
|
-
const p3 = rv.RunView<
|
|
361
|
-
EntityName: "User Roles",
|
|
360
|
+
const p3 = rv.RunView<MJUserRoleEntity>({
|
|
361
|
+
EntityName: "MJ: User Roles",
|
|
362
362
|
ResultType: 'entity_object'
|
|
363
363
|
}, u);
|
|
364
364
|
|
|
@@ -384,7 +384,7 @@ export class SyncRolesAndUsersResolver {
|
|
|
384
384
|
// now we need to make sure there is a user role that matches this user and role
|
|
385
385
|
if (!dbUserRoles.find(ur => ur.UserID === dbUser.ID && ur.RoleID === dbRole.ID)) {
|
|
386
386
|
// we need to add a user role
|
|
387
|
-
const ur = await md.GetEntityObject<
|
|
387
|
+
const ur = await md.GetEntityObject<MJUserRoleEntity>("MJ: User Roles", u);
|
|
388
388
|
ur.UserID = dbUser.ID;
|
|
389
389
|
ur.RoleID = dbRole.ID;
|
|
390
390
|
ok = ok && await ur.Save();
|
|
@@ -71,13 +71,13 @@ export class UserFavoriteResolver extends MJUserFavoriteResolverBase {
|
|
|
71
71
|
@Query(() => [MJUserFavorite_])
|
|
72
72
|
async UserFavoritesByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
73
73
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
74
|
-
return await this.findBy(provider, 'User Favorites', { UserID }, userPayload.userRecord);
|
|
74
|
+
return await this.findBy(provider, 'MJ: User Favorites', { UserID }, userPayload.userRecord);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
@Query(() => [MJUserFavorite_])
|
|
78
78
|
async UserFavoriteSearchByParams(@Arg('params', () => Int) params: UserFavoriteSearchParams, @Ctx() { providers, userPayload }: AppContext) {
|
|
79
79
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
80
|
-
return await this.findBy(provider, 'User Favorites', params, userPayload.userRecord);
|
|
80
|
+
return await this.findBy(provider, 'MJ: User Favorites', params, userPayload.userRecord);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
@Query(() => UserFavoriteResult)
|
|
@@ -30,7 +30,7 @@ export class UserResolver extends MJUserResolverBase {
|
|
|
30
30
|
__mj_CreatedAt: userRecord.__mj_CreatedAt,
|
|
31
31
|
__mj_UpdatedAt: userRecord.__mj_UpdatedAt,
|
|
32
32
|
// Include the UserRoles sub-array for the GraphQL response
|
|
33
|
-
|
|
33
|
+
MJUserRoles_UserIDArray: userRecord.UserRoles?.map((r: { ID: string; UserID: string; RoleID: string; RoleName?: string; __mj_CreatedAt?: Date; __mj_UpdatedAt?: Date }) => ({
|
|
34
34
|
ID: r.ID,
|
|
35
35
|
UserID: r.UserID,
|
|
36
36
|
RoleID: r.RoleID,
|
|
@@ -41,7 +41,7 @@ export class UserResolver extends MJUserResolverBase {
|
|
|
41
41
|
})) || [],
|
|
42
42
|
};
|
|
43
43
|
console.log('CurrentUser (from userRecord)', userData.Email);
|
|
44
|
-
return this.MapFieldNamesToCodeNames('Users', userData);
|
|
44
|
+
return this.MapFieldNamesToCodeNames('MJ: Users', userData);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// Fall back to email lookup for JWT-based auth
|
|
@@ -56,8 +56,8 @@ export class UserResolver extends MJUserResolverBase {
|
|
|
56
56
|
await this.CheckAPIKeyScopeAuthorization('user:read', ID.toString(), userPayload);
|
|
57
57
|
|
|
58
58
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
59
|
-
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { ID }, userPayload.userRecord));
|
|
60
|
-
return this.MapFieldNamesToCodeNames('Users', retVal);
|
|
59
|
+
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'MJ: Users', { ID }, userPayload.userRecord));
|
|
60
|
+
return this.MapFieldNamesToCodeNames('MJ: Users', retVal);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
@Query(() => MJUser_)
|
|
@@ -66,8 +66,8 @@ export class UserResolver extends MJUserResolverBase {
|
|
|
66
66
|
await this.CheckAPIKeyScopeAuthorization('user:read', EmployeeID.toString(), userPayload);
|
|
67
67
|
|
|
68
68
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
69
|
-
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { EmployeeID }, userPayload.userRecord));
|
|
70
|
-
return this.MapFieldNamesToCodeNames('Users', retVal);
|
|
69
|
+
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'MJ: Users', { EmployeeID }, userPayload.userRecord));
|
|
70
|
+
return this.MapFieldNamesToCodeNames('MJ: Users', retVal);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
@Query(() => MJUser_)
|
|
@@ -78,8 +78,8 @@ export class UserResolver extends MJUserResolverBase {
|
|
|
78
78
|
// const searchEmail = userEmailMap[Email] ?? Email;
|
|
79
79
|
const searchEmail = Email;
|
|
80
80
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
81
|
-
const returnVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { Email: searchEmail }, userPayload.userRecord));
|
|
82
|
-
return this.MapFieldNamesToCodeNames('Users', returnVal);
|
|
81
|
+
const returnVal = super.safeFirstArrayElement(await this.findBy(provider, 'MJ: Users', { Email: searchEmail }, userPayload.userRecord));
|
|
82
|
+
return this.MapFieldNamesToCodeNames('MJ: Users', returnVal);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
export default UserResolver;
|
|
@@ -3,7 +3,7 @@ import { EntitySaveOptions, Metadata } from '@memberjunction/core';
|
|
|
3
3
|
import { AppContext, Arg, Ctx, Int, Query, Resolver, UserPayload } from '@memberjunction/server';
|
|
4
4
|
import { MJUserView_, MJUserViewResolverBase } from '../generated/generated.js';
|
|
5
5
|
import { UserResolver } from './UserResolver.js';
|
|
6
|
-
import {
|
|
6
|
+
import { MJUserViewEntity, UserViewEntityExtended } from '@memberjunction/core-entities';
|
|
7
7
|
import { GetReadOnlyProvider } from '../util.js';
|
|
8
8
|
|
|
9
9
|
@Resolver(MJUserView_)
|
|
@@ -11,7 +11,7 @@ export class UserViewResolver extends MJUserViewResolverBase {
|
|
|
11
11
|
@Query(() => [MJUserView_])
|
|
12
12
|
async UserViewsByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
13
13
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
14
|
-
return await this.findBy(provider, 'User Views', { UserID }, userPayload.userRecord);
|
|
14
|
+
return await this.findBy(provider, 'MJ: User Views', { UserID }, userPayload.userRecord);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
@Query(() => [MJUserView_])
|
|
@@ -21,13 +21,13 @@ export class UserViewResolver extends MJUserViewResolverBase {
|
|
|
21
21
|
@Ctx() { providers, userPayload }: AppContext
|
|
22
22
|
) {
|
|
23
23
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
24
|
-
return await this.findBy(provider, 'User Views', { UserID, EntityID, IsDefault: true }, userPayload.userRecord);
|
|
24
|
+
return await this.findBy(provider, 'MJ: User Views', { UserID, EntityID, IsDefault: true }, userPayload.userRecord);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
@Query(() => [MJUserView_])
|
|
28
28
|
async CurrentUserDefaultViewByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
|
|
29
29
|
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
30
|
-
return await this.findBy(provider, 'User Views', {
|
|
30
|
+
return await this.findBy(provider, 'MJ: User Views', {
|
|
31
31
|
UserID: await this.getCurrentUserID(context),
|
|
32
32
|
EntityID,
|
|
33
33
|
IsDefault: true,
|
|
@@ -43,7 +43,7 @@ export class UserViewResolver extends MJUserViewResolverBase {
|
|
|
43
43
|
@Query(() => [MJUserView_])
|
|
44
44
|
async CurrentUserUserViewsByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
|
|
45
45
|
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
46
|
-
return this.findBy(provider, 'User Views', { UserID: await this.getCurrentUserID(context), EntityID}, context.userPayload.userRecord);
|
|
46
|
+
return this.findBy(provider, 'MJ: User Views', { UserID: await this.getCurrentUserID(context), EntityID}, context.userPayload.userRecord);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
@Query(() => [MJUserView_])
|
|
@@ -54,7 +54,7 @@ export class UserViewResolver extends MJUserViewResolverBase {
|
|
|
54
54
|
// filter state which in turn will be used to update the where clause in the entity sub-class.
|
|
55
55
|
const p = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
|
|
56
56
|
const u = this.GetUserFromPayload(userPayload);
|
|
57
|
-
const viewEntity = <UserViewEntityExtended>await p.GetEntityObject('User Views', u);
|
|
57
|
+
const viewEntity = <UserViewEntityExtended>await p.GetEntityObject('MJ: User Views', u);
|
|
58
58
|
await viewEntity.Load(ID);
|
|
59
59
|
viewEntity.UpdateWhereClause();
|
|
60
60
|
|