@memberjunction/server 2.7.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -99,11 +99,14 @@ export class AskSkipResolver {
99
99
  if (!user) throw new Error(`User ${userPayload.email} not found in UserCache`);
100
100
 
101
101
  // now load up the messages. We will load up ALL of the messages for this conversation, and then pass them to the Skip API
102
- const messages: SkipMessage[] = await this.LoadConversationDetailsIntoSkipMessages(
103
- dataSource,
104
- ConversationId,
105
- AskSkipResolver._maxHistoricalMessages
106
- );
102
+ let messages: SkipMessage[] = [];
103
+ if (ConversationId && ConversationId.length > 0) {
104
+ messages = await this.LoadConversationDetailsIntoSkipMessages(
105
+ dataSource,
106
+ ConversationId,
107
+ AskSkipResolver._maxHistoricalMessages
108
+ );
109
+ }
107
110
 
108
111
  const md = new Metadata();
109
112
  const { convoEntity, dataContextEntity, convoDetailEntity, dataContext } = await this.HandleSkipInitialObjectLoading(
@@ -375,9 +378,11 @@ export class AskSkipResolver {
375
378
  protected BuildSkipEntities(): SkipEntityInfo[] {
376
379
  // build the entity info for skip in its format which is
377
380
  // narrower in scope than our native MJ metadata
378
- // don't pass the mj_core_schema entities
381
+ // don't pass the mj_core_schema entities by default, but allow flexibilty
382
+ // to include specific entities from the MJAPI config.json
383
+ const includedEntities = configInfo.askSkip.entitiesToSendSkip.includeEntitiesFromExcludedSchemas.map((e) => e.trim().toLowerCase());
379
384
  const md = new Metadata();
380
- return md.Entities.filter((e) => e.SchemaName !== mj_core_schema).map((e) => {
385
+ return md.Entities.filter((e) => e.SchemaName !== mj_core_schema || includedEntities.includes(e.Name.trim().toLowerCase())).map((e) => {
381
386
  const ret: SkipEntityInfo = {
382
387
  id: e.ID,
383
388
  name: e.Name,
@@ -465,12 +470,13 @@ export class AskSkipResolver {
465
470
  if (!DataContextId || DataContextId.length === 0) {
466
471
  dataContextEntity.NewRecord();
467
472
  dataContextEntity.UserID = user.ID;
468
- dataContextEntity.Name = 'Data Context for Skip Conversation';
473
+ dataContextEntity.Name = 'Data Context for Skip Conversation ';
469
474
  if (!(await dataContextEntity.Save())) {
470
475
  LogError(`Creating a new data context failed`, undefined, dataContextEntity.LatestResult);
471
476
  throw new Error(`Creating a new data context failed`);
472
477
  }
473
- } else {
478
+ }
479
+ else {
474
480
  const dcLoadResult = await dataContextEntity.Load(DataContextId);
475
481
  if (!dcLoadResult) {
476
482
  throw new Error(`Loading DataContextEntity for DataContextId ${DataContextId} failed`);
@@ -487,32 +493,61 @@ export class AskSkipResolver {
487
493
  LogError(`Error saving DataContextEntity for conversation: ${ConversationId}`, undefined, dataContextEntity.LatestResult);
488
494
  }
489
495
  }
490
- } else {
496
+ }
497
+ else {
491
498
  LogError(`Creating a new conversation failed`, undefined, convoEntity.LatestResult);
492
499
  throw new Error(`Creating a new conversation failed`);
493
500
  }
494
- } else {
501
+ }
502
+ else {
495
503
  throw new Error(`User ${userPayload.email} not found in UserCache`);
496
504
  }
497
- } else {
505
+ }
506
+ else {
498
507
  await convoEntity.Load(ConversationId); // load the existing conversation, will need it later
499
508
  dataContextEntity = await md.GetEntityObject<DataContextEntity>('Data Contexts', user);
500
509
 
501
- // note - we ignore the parameter DataContextId if it is passed in, we will use the data context from the conversation that is saved. If a user wants to change the data context for a convo, they can do that elsewhere
510
+ // check to see if the DataContextId is passed in and if it is different than the DataContextID in the conversation
502
511
  if (DataContextId && DataContextId.length > 0 && DataContextId !== convoEntity.DataContextID) {
503
512
  if (convoEntity.DataContextID === null) {
513
+ // use the DataContextId passed in if the conversation doesn't have a DataContextID
504
514
  convoEntity.DataContextID = DataContextId;
505
515
  const convoEntitySaveResult: boolean = await convoEntity.Save();
506
516
  if (!convoEntitySaveResult) {
507
517
  LogError(`Error saving conversation entity for conversation: ${ConversationId}`, undefined, convoEntity.LatestResult);
508
518
  }
509
- } else
519
+ }
520
+ else {
521
+ // note - we ignore the parameter DataContextId if it is passed in, we will use the data context from the conversation that is saved.
522
+ // If a user wants to change the data context for a convo, they can do that elsewhere
510
523
  console.warn(
511
524
  `AskSkipResolver: DataContextId ${DataContextId} was passed in but it was ignored because it was different than the DataContextID in the conversation ${convoEntity.DataContextID}`
512
525
  );
526
+ }
527
+ // only load if we have a data context here, otherwise we have a new record in the dataContext entity
528
+ if (convoEntity.DataContextID)
529
+ await dataContextEntity.Load(convoEntity.DataContextID);
530
+ }
531
+ else if ((!DataContextId || DataContextId.length === 0) && (!convoEntity.DataContextID || convoEntity.DataContextID.length === 0)) {
532
+ // in this branch of the logic we don't have a passed in DataContextId and we don't have a DataContextID in the conversation, so we need to save the data context, get the ID,
533
+ // update the conversation and save it as well
534
+ dataContextEntity.NewRecord();
535
+ dataContextEntity.UserID = user.ID;
536
+ dataContextEntity.Name = 'Data Context for Skip Conversation ' + ConversationId;
537
+ if (await dataContextEntity.Save()) {
538
+ DataContextId = convoEntity.DataContextID;
539
+ convoEntity.DataContextID = dataContextEntity.ID;
540
+ if (!await convoEntity.Save()) {
541
+ LogError(`Error saving conversation entity for conversation: ${ConversationId}`, undefined, convoEntity.LatestResult);
542
+ }
543
+ }
544
+ else
545
+ LogError(`Error saving DataContextEntity for conversation: ${ConversationId}`, undefined, dataContextEntity.LatestResult);
546
+ }
547
+ else {
548
+ // finally in this branch we get here if we have a DataContextId passed in and it is the same as the DataContextID in the conversation, in this case simply load the data context
549
+ await dataContextEntity.Load(convoEntity.DataContextID);
513
550
  }
514
-
515
- await dataContextEntity.Load(convoEntity.DataContextID);
516
551
  }
517
552
 
518
553
  // now, create a conversation detail record for the user message
@@ -528,7 +563,7 @@ export class AskSkipResolver {
528
563
  LogError(`Error saving conversation detail entity for user message: ${UserQuestion}`, undefined, convoDetailEntity.LatestResult);
529
564
  }
530
565
 
531
- const dataContext = MJGlobal.Instance.ClassFactory.CreateInstance<DataContext>(DataContext); // await this.LoadDataContext(md, dataSource, dataContextEntity, user, false);
566
+ const dataContext = MJGlobal.Instance.ClassFactory.CreateInstance<DataContext>(DataContext);
532
567
  await dataContext.Load(dataContextEntity.ID, dataSource, false, false, 0, user);
533
568
  return { dataContext, convoEntity, dataContextEntity, convoDetailEntity };
534
569
  }
@@ -539,6 +574,10 @@ export class AskSkipResolver {
539
574
  maxHistoricalMessages?: number
540
575
  ): Promise<SkipMessage[]> {
541
576
  try {
577
+ if (!ConversationId || ConversationId.length === 0) {
578
+ throw new Error(`ConversationId is required`);
579
+ }
580
+
542
581
  // load up all the conversation details from the database server
543
582
  const md = new Metadata();
544
583
  const e = md.Entities.find((e) => e.Name === 'Conversation Details');
@@ -551,7 +590,8 @@ export class AskSkipResolver {
551
590
  ORDER
552
591
  BY __mj_CreatedAt DESC`;
553
592
  const result = await dataSource.query(sql);
554
- if (!result) throw new Error(`Error running SQL: ${sql}`);
593
+ if (!result)
594
+ throw new Error(`Error running SQL: ${sql}`);
555
595
  else {
556
596
  // first, let's sort the result array into a local variable called returnData and in that we will sort by __mj_CreatedAt in ASCENDING order so we have the right chronological order
557
597
  // the reason we're doing a LOCAL sort here is because in the SQL query above, we're sorting in DESCENDING order so we can use the TOP clause to limit the number of records and get the