@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.
Files changed (115) hide show
  1. package/dist/agents/skip-agent.js +9 -9
  2. package/dist/agents/skip-agent.js.map +1 -1
  3. package/dist/apolloServer/TransactionPlugin.d.ts +4 -0
  4. package/dist/apolloServer/TransactionPlugin.d.ts.map +1 -0
  5. package/dist/apolloServer/TransactionPlugin.js +46 -0
  6. package/dist/apolloServer/TransactionPlugin.js.map +1 -0
  7. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  8. package/dist/auth/__tests__/backward-compatibility.test.d.ts +2 -0
  9. package/dist/auth/__tests__/backward-compatibility.test.d.ts.map +1 -0
  10. package/dist/auth/__tests__/backward-compatibility.test.js +135 -0
  11. package/dist/auth/__tests__/backward-compatibility.test.js.map +1 -0
  12. package/dist/auth/exampleNewUserSubClass.d.ts +2 -2
  13. package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
  14. package/dist/auth/index.js.map +1 -1
  15. package/dist/auth/newUsers.d.ts +2 -2
  16. package/dist/auth/newUsers.d.ts.map +1 -1
  17. package/dist/auth/newUsers.js +6 -6
  18. package/dist/auth/newUsers.js.map +1 -1
  19. package/dist/entitySubclasses/entityPermissions.server.d.ts +2 -2
  20. package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
  21. package/dist/entitySubclasses/entityPermissions.server.js +3 -3
  22. package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
  23. package/dist/generated/generated.d.ts +10724 -10721
  24. package/dist/generated/generated.d.ts.map +1 -1
  25. package/dist/generated/generated.js +48710 -48698
  26. package/dist/generated/generated.js.map +1 -1
  27. package/dist/generic/DeleteOptionsInput.d.ts +12 -2
  28. package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
  29. package/dist/generic/DeleteOptionsInput.js +12 -2
  30. package/dist/generic/DeleteOptionsInput.js.map +1 -1
  31. package/dist/generic/ResolverBase.d.ts.map +1 -1
  32. package/dist/generic/ResolverBase.js +6 -6
  33. package/dist/generic/ResolverBase.js.map +1 -1
  34. package/dist/generic/RunViewResolver.js +3 -3
  35. package/dist/generic/RunViewResolver.js.map +1 -1
  36. package/dist/resolvers/AskSkipResolver.d.ts +123 -0
  37. package/dist/resolvers/AskSkipResolver.d.ts.map +1 -0
  38. package/dist/resolvers/AskSkipResolver.js +1788 -0
  39. package/dist/resolvers/AskSkipResolver.js.map +1 -0
  40. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  41. package/dist/resolvers/CreateQueryResolver.d.ts +3 -3
  42. package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
  43. package/dist/resolvers/CreateQueryResolver.js +19 -19
  44. package/dist/resolvers/CreateQueryResolver.js.map +1 -1
  45. package/dist/resolvers/EntityResolver.js +1 -1
  46. package/dist/resolvers/EntityResolver.js.map +1 -1
  47. package/dist/resolvers/FileCategoryResolver.js +4 -4
  48. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  49. package/dist/resolvers/FileResolver.js +20 -20
  50. package/dist/resolvers/FileResolver.js.map +1 -1
  51. package/dist/resolvers/GetDataContextDataResolver.js +1 -1
  52. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  53. package/dist/resolvers/ISAEntityResolver.d.ts +22 -1
  54. package/dist/resolvers/ISAEntityResolver.d.ts.map +1 -1
  55. package/dist/resolvers/ISAEntityResolver.js +77 -1
  56. package/dist/resolvers/ISAEntityResolver.js.map +1 -1
  57. package/dist/resolvers/ReportResolver.js +3 -3
  58. package/dist/resolvers/ReportResolver.js.map +1 -1
  59. package/dist/resolvers/RunAIAgentResolver.js +3 -3
  60. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  61. package/dist/resolvers/RunAIPromptResolver.js +1 -1
  62. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  63. package/dist/resolvers/RunTemplateResolver.js +2 -2
  64. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  65. package/dist/resolvers/SyncDataResolver.js +1 -1
  66. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  67. package/dist/resolvers/SyncRolesUsersResolver.d.ts +9 -9
  68. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  69. package/dist/resolvers/SyncRolesUsersResolver.js +10 -10
  70. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  71. package/dist/resolvers/UserFavoriteResolver.js +2 -2
  72. package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
  73. package/dist/resolvers/UserResolver.js +8 -8
  74. package/dist/resolvers/UserResolver.js.map +1 -1
  75. package/dist/resolvers/UserViewResolver.js +5 -5
  76. package/dist/resolvers/UserViewResolver.js.map +1 -1
  77. package/dist/rest/ViewOperationsHandler.js +1 -1
  78. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  79. package/dist/scheduler/LearningCycleScheduler.d.ts +4 -0
  80. package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -0
  81. package/dist/scheduler/LearningCycleScheduler.js +4 -0
  82. package/dist/scheduler/LearningCycleScheduler.js.map +1 -0
  83. package/dist/services/TaskOrchestrator.d.ts +1 -1
  84. package/dist/services/TaskOrchestrator.js +5 -5
  85. package/dist/services/TaskOrchestrator.js.map +1 -1
  86. package/package.json +52 -52
  87. package/src/agents/skip-agent.ts +9 -9
  88. package/src/auth/APIKeyScopeAuth.ts +5 -5
  89. package/src/auth/exampleNewUserSubClass.ts +2 -2
  90. package/src/auth/index.ts +3 -3
  91. package/src/auth/newUsers.ts +9 -9
  92. package/src/entitySubclasses/entityPermissions.server.ts +3 -3
  93. package/src/generated/generated.ts +31186 -31177
  94. package/src/generic/DeleteOptionsInput.ts +12 -2
  95. package/src/generic/ResolverBase.ts +7 -7
  96. package/src/generic/RunViewResolver.ts +3 -3
  97. package/src/resolvers/APIKeyResolver.ts +2 -2
  98. package/src/resolvers/ComponentRegistryResolver.ts +9 -9
  99. package/src/resolvers/CreateQueryResolver.ts +18 -18
  100. package/src/resolvers/EntityResolver.ts +1 -1
  101. package/src/resolvers/FileCategoryResolver.ts +5 -5
  102. package/src/resolvers/FileResolver.ts +27 -27
  103. package/src/resolvers/GetDataContextDataResolver.ts +2 -2
  104. package/src/resolvers/ISAEntityResolver.ts +77 -1
  105. package/src/resolvers/ReportResolver.ts +4 -4
  106. package/src/resolvers/RunAIAgentResolver.ts +7 -7
  107. package/src/resolvers/RunAIPromptResolver.ts +1 -1
  108. package/src/resolvers/RunTemplateResolver.ts +4 -4
  109. package/src/resolvers/SyncDataResolver.ts +3 -3
  110. package/src/resolvers/SyncRolesUsersResolver.ts +26 -26
  111. package/src/resolvers/UserFavoriteResolver.ts +2 -2
  112. package/src/resolvers/UserResolver.ts +8 -8
  113. package/src/resolvers/UserViewResolver.ts +6 -6
  114. package/src/rest/ViewOperationsHandler.ts +1 -1
  115. 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 a GraphQL endpoint for client-side code to discover child entity
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 { ConversationDetailEntity, ReportEntity } from '@memberjunction/core-entities';
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<ReportEntity>('Reports', u);
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 { ConversationDetailEntity, ConversationDetailAttachmentEntity } from '@memberjunction/core-entities';
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<ConversationDetailEntity>(
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<ConversationDetailEntity>(
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<ConversationDetailEntity>({
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 { TemplateContentEntity, TemplateEntityExtended } from '@memberjunction/core-entities';
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<TemplateContentEntity>({
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 { DatasetItemEntity } from '@memberjunction/core-entities';
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<DatasetItemEntity>({
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 { RoleEntity, UserEntity, UserRoleEntity } from '@memberjunction/core-entities';
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<RoleEntity>({
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: RoleEntity[], futureRoles: RoleInputType[], userPayload: UserPayload): Promise<SyncRolesAndUsersResultType> {
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: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
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<RoleEntity>("Roles", user);
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: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
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: RoleEntity, rv: RunView, user: UserInfo, userPayload: UserPayload): Promise<boolean> {
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<UserRoleEntity>({
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<UserEntity>({
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: UserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
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: UserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
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<UserEntity>("Users", userPayload.userRecord);
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: UserEntity[], futureUsers: UserInputType[], u: UserInfo, userPayload: UserPayload): Promise<boolean> {
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: UserEntity, rv: RunView, u: UserInfo, userPayload: UserPayload): Promise<boolean> {
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<UserRoleEntity>({
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<UserEntity>({
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<RoleEntity>({
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<UserRoleEntity>({
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<UserRoleEntity>("User Roles", u);
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
- UserRoles_UserIDArray: userRecord.UserRoles?.map((r: { ID: string; UserID: string; RoleID: string; RoleName?: string; __mj_CreatedAt?: Date; __mj_UpdatedAt?: Date }) => ({
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 { UserViewEntity, UserViewEntityExtended } from '@memberjunction/core-entities';
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
 
@@ -142,7 +142,7 @@ export class ViewOperationsHandler {
142
142
 
143
143
  // Run a view to get the available views
144
144
  const params: RunViewParams = {
145
- EntityName: 'User Views',
145
+ EntityName: 'MJ: User Views',
146
146
  ExtraFilter: `Entity = '${entityName}'`
147
147
  };
148
148