@memberjunction/server 2.98.0 → 2.100.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 (34) hide show
  1. package/dist/config.d.ts +213 -0
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +15 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/generated/generated.d.ts +6 -0
  6. package/dist/generated/generated.d.ts.map +1 -1
  7. package/dist/generated/generated.js +32 -0
  8. package/dist/generated/generated.js.map +1 -1
  9. package/dist/generic/RunViewResolver.d.ts +5 -3
  10. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  11. package/dist/generic/RunViewResolver.js +30 -18
  12. package/dist/generic/RunViewResolver.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/resolvers/AskSkipResolver.d.ts +4 -0
  18. package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
  19. package/dist/resolvers/AskSkipResolver.js +11 -5
  20. package/dist/resolvers/AskSkipResolver.js.map +1 -1
  21. package/dist/resolvers/ComponentRegistryResolver.d.ts +49 -0
  22. package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -0
  23. package/dist/resolvers/ComponentRegistryResolver.js +448 -0
  24. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -0
  25. package/dist/resolvers/FileResolver.js +2 -2
  26. package/dist/resolvers/FileResolver.js.map +1 -1
  27. package/package.json +40 -40
  28. package/src/config.ts +17 -0
  29. package/src/generated/generated.ts +20 -0
  30. package/src/generic/RunViewResolver.ts +30 -15
  31. package/src/index.ts +1 -0
  32. package/src/resolvers/AskSkipResolver.ts +15 -6
  33. package/src/resolvers/ComponentRegistryResolver.ts +535 -0
  34. package/src/resolvers/FileResolver.ts +2 -2
@@ -2768,6 +2768,10 @@ if this limit is exceeded.`})
2768
2768
  @Field(() => Int, {nullable: true, description: `Default effort level for all prompts executed by this agent (1-100, where 1=minimal effort, 100=maximum effort). Takes precedence over individual prompt EffortLevel settings but can be overridden by runtime parameters. Inherited by sub-agents unless explicitly overridden.`})
2769
2769
  DefaultPromptEffortLevel?: number;
2770
2770
 
2771
+ @Field({nullable: true, description: `Controls how Chat next steps are handled. When null (default), Chat propagates to caller. When set to Success, Failed, or Retry, Chat steps are remapped to that value and re-validated.`})
2772
+ @MaxLength(60)
2773
+ ChatHandlingOption?: string;
2774
+
2771
2775
  @Field({nullable: true})
2772
2776
  @MaxLength(510)
2773
2777
  Parent?: string;
@@ -2930,6 +2934,9 @@ export class CreateAIAgentInput {
2930
2934
 
2931
2935
  @Field(() => Int, { nullable: true })
2932
2936
  DefaultPromptEffortLevel: number | null;
2937
+
2938
+ @Field({ nullable: true })
2939
+ ChatHandlingOption: string | null;
2933
2940
  }
2934
2941
 
2935
2942
 
@@ -3040,6 +3047,9 @@ export class UpdateAIAgentInput {
3040
3047
  @Field(() => Int, { nullable: true })
3041
3048
  DefaultPromptEffortLevel?: number | null;
3042
3049
 
3050
+ @Field({ nullable: true })
3051
+ ChatHandlingOption?: string | null;
3052
+
3043
3053
  @Field(() => [KeyValuePairInput], { nullable: true })
3044
3054
  OldValues___?: KeyValuePairInput[];
3045
3055
  }
@@ -39164,6 +39174,10 @@ export class ComponentLibrary_ {
39164
39174
  @Field({nullable: true, description: `JSON object defining dependencies for this component library. Format: { "libraryName": "versionSpec", ... }. Version specifications follow NPM-style syntax (e.g., "~1.0.0", "^1.2.3", "2.3.4"). Dependencies are loaded before this library to ensure proper execution context.`})
39165
39175
  Dependencies?: string;
39166
39176
 
39177
+ @Field({description: `Controls how the library can be used: Direct (by components), Dependency (only as dependency), or Both`})
39178
+ @MaxLength(100)
39179
+ UsageType: string;
39180
+
39167
39181
  @Field(() => [ComponentLibraryLink_])
39168
39182
  MJ_ComponentLibraryLinks_LibraryIDArray: ComponentLibraryLink_[]; // Link to MJ_ComponentLibraryLinks
39169
39183
 
@@ -39209,6 +39223,9 @@ export class CreateComponentLibraryInput {
39209
39223
 
39210
39224
  @Field({ nullable: true })
39211
39225
  Dependencies: string | null;
39226
+
39227
+ @Field({ nullable: true })
39228
+ UsageType?: string;
39212
39229
  }
39213
39230
 
39214
39231
 
@@ -39253,6 +39270,9 @@ export class UpdateComponentLibraryInput {
39253
39270
  @Field({ nullable: true })
39254
39271
  Dependencies?: string | null;
39255
39272
 
39273
+ @Field({ nullable: true })
39274
+ UsageType?: string;
39275
+
39256
39276
  @Field(() => [KeyValuePairInput], { nullable: true })
39257
39277
  OldValues___?: KeyValuePairInput[];
39258
39278
  }
@@ -1,10 +1,11 @@
1
1
  import { Arg, Ctx, Field, InputType, Int, ObjectType, PubSubEngine, Query, Resolver } from 'type-graphql';
2
2
  import { AppContext } from '../types.js';
3
3
  import { ResolverBase } from './ResolverBase.js';
4
- import { LogError, LogStatus } from '@memberjunction/core';
4
+ import { LogError, LogStatus, EntityInfo } from '@memberjunction/core';
5
5
  import { RequireSystemUser } from '../directives/RequireSystemUser.js';
6
6
  import { GetReadOnlyProvider } from '../util.js';
7
7
  import { UserViewEntityExtended } from '@memberjunction/core-entities';
8
+ import { KeyValuePairOutputType } from './KeyInputOutputTypes.js';
8
9
 
9
10
  /********************************************************************************
10
11
  * The PURPOSE of this resolver is to provide a generic way to run a view and return the results.
@@ -384,8 +385,10 @@ export class RunViewGenericInput {
384
385
 
385
386
  @ObjectType()
386
387
  export class RunViewResultRow {
387
- @Field(() => String)
388
- ID: string;
388
+ @Field(() => [KeyValuePairOutputType], {
389
+ description: 'Primary key values for the record'
390
+ })
391
+ PrimaryKey: KeyValuePairOutputType[];
389
392
 
390
393
  @Field(() => String)
391
394
  EntityID: string;
@@ -396,8 +399,10 @@ export class RunViewResultRow {
396
399
 
397
400
  @ObjectType()
398
401
  export class RunViewGenericResultRow {
399
- @Field(() => String)
400
- ID: string;
402
+ @Field(() => [KeyValuePairOutputType], {
403
+ description: 'Primary key values for the record'
404
+ })
405
+ PrimaryKey: KeyValuePairOutputType[];
401
406
 
402
407
  @Field(() => String)
403
408
  EntityID: string;
@@ -469,7 +474,8 @@ export class RunViewResolver extends ResolverBase {
469
474
  return null;
470
475
 
471
476
  const viewInfo = super.safeFirstArrayElement<UserViewEntityExtended>(await super.findBy<UserViewEntityExtended>(provider, "User Views", { Name: input.ViewName }, userPayload.userRecord));
472
- const returnData = this.processRawData(rawData.Results, viewInfo.EntityID);
477
+ const entity = provider.Entities.find((e) => e.ID === viewInfo.EntityID);
478
+ const returnData = this.processRawData(rawData.Results, viewInfo.EntityID, entity);
473
479
  return {
474
480
  Results: returnData,
475
481
  UserViewRunID: rawData?.UserViewRunID,
@@ -496,7 +502,8 @@ export class RunViewResolver extends ResolverBase {
496
502
  return null;
497
503
 
498
504
  const viewInfo = super.safeFirstArrayElement<UserViewEntityExtended>(await super.findBy<UserViewEntityExtended>(provider, "User Views", { ID: input.ViewID }, userPayload.userRecord));
499
- const returnData = this.processRawData(rawData.Results, viewInfo.EntityID);
505
+ const entity = provider.Entities.find((e) => e.ID === viewInfo.EntityID);
506
+ const returnData = this.processRawData(rawData.Results, viewInfo.EntityID, entity);
500
507
  return {
501
508
  Results: returnData,
502
509
  UserViewRunID: rawData?.UserViewRunID,
@@ -522,7 +529,7 @@ export class RunViewResolver extends ResolverBase {
522
529
  if (rawData === null) return null;
523
530
 
524
531
  const entity = provider.Entities.find((e) => e.Name === input.EntityName);
525
- const returnData = this.processRawData(rawData.Results, entity.ID);
532
+ const returnData = this.processRawData(rawData.Results, entity.ID, entity);
526
533
  return {
527
534
  Results: returnData,
528
535
  UserViewRunID: rawData?.UserViewRunID,
@@ -552,7 +559,7 @@ export class RunViewResolver extends ResolverBase {
552
559
  let results: RunViewGenericResult[] = [];
553
560
  for (const [index, data] of rawData.entries()) {
554
561
  const entity = provider.Entities.find((e) => e.Name === input[index].EntityName);
555
- const returnData: any[] = this.processRawData(data.Results, entity.ID);
562
+ const returnData: any[] = this.processRawData(data.Results, entity.ID, entity);
556
563
 
557
564
  results.push({
558
565
  Results: returnData,
@@ -594,7 +601,7 @@ export class RunViewResolver extends ResolverBase {
594
601
 
595
602
  const entity = provider.Entities.find((e) => e.Name === input.ViewName);
596
603
  const entityId = entity ? entity.ID : null;
597
- const returnData = this.processRawData(rawData.Results, entityId);
604
+ const returnData = this.processRawData(rawData.Results, entityId, entity);
598
605
  return {
599
606
  Results: returnData,
600
607
  UserViewRunID: rawData?.UserViewRunID,
@@ -640,7 +647,8 @@ export class RunViewResolver extends ResolverBase {
640
647
  }
641
648
 
642
649
  const viewInfo = super.safeFirstArrayElement<UserViewEntityExtended>(await super.findBy<UserViewEntityExtended>(provider, "User Views", { ID: input.ViewID }, userPayload.userRecord));
643
- const returnData = this.processRawData(rawData.Results, viewInfo.EntityID);
650
+ const entity = provider.Entities.find((e) => e.ID === viewInfo.EntityID);
651
+ const returnData = this.processRawData(rawData.Results, viewInfo.EntityID, entity);
644
652
  return {
645
653
  Results: returnData,
646
654
  UserViewRunID: rawData?.UserViewRunID,
@@ -698,7 +706,7 @@ export class RunViewResolver extends ResolverBase {
698
706
  ExecutionTime: 0
699
707
  };
700
708
  }
701
- const returnData = this.processRawData(rawData.Results, entity.ID);
709
+ const returnData = this.processRawData(rawData.Results, entity.ID, entity);
702
710
  return {
703
711
  Results: returnData,
704
712
  UserViewRunID: rawData?.UserViewRunID,
@@ -743,7 +751,7 @@ export class RunViewResolver extends ResolverBase {
743
751
  LogError(new Error(`Entity with name ${input[index].EntityName} not found`));
744
752
  continue;
745
753
  }
746
- const returnData: any[] = this.processRawData(data.Results, entity.ID);
754
+ const returnData: any[] = this.processRawData(data.Results, entity.ID, entity);
747
755
 
748
756
  results.push({
749
757
  Results: returnData,
@@ -763,12 +771,19 @@ export class RunViewResolver extends ResolverBase {
763
771
  }
764
772
  }
765
773
 
766
- protected processRawData(rawData: any[], entityId: string): RunViewResultRow[] {
774
+ protected processRawData(rawData: any[], entityId: string, entityInfo: EntityInfo): RunViewResultRow[] {
767
775
  const returnResult = [];
768
776
  for (let i = 0; i < rawData.length; i++) {
769
777
  const row = rawData[i];
778
+
779
+ // Build the primary key array from the entity's primary key fields
780
+ const primaryKey: KeyValuePairOutputType[] = entityInfo.PrimaryKeys.map(pk => ({
781
+ FieldName: pk.Name,
782
+ Value: row[pk.Name]?.toString() || ''
783
+ }));
784
+
770
785
  returnResult.push({
771
- ID: row.ID.toString(),
786
+ PrimaryKey: primaryKey,
772
787
  EntityID: entityId,
773
788
  Data: JSON.stringify(row),
774
789
  });
package/src/index.ts CHANGED
@@ -92,6 +92,7 @@ export * from './generic/DeleteOptionsInput.js';
92
92
 
93
93
  export * from './resolvers/AskSkipResolver.js';
94
94
  export * from './resolvers/ColorResolver.js';
95
+ export * from './resolvers/ComponentRegistryResolver.js';
95
96
  export * from './resolvers/DatasetResolver.js';
96
97
  export * from './resolvers/EntityRecordNameResolver.js';
97
98
  export * from './resolvers/MergeRecordsResolver.js';
@@ -54,7 +54,7 @@ import {
54
54
  UserNotificationEntity,
55
55
  AIAgentEntityExtended
56
56
  } from '@memberjunction/core-entities';
57
- import { apiKey, baseUrl, publicUrl, configInfo, graphqlPort, graphqlRootPath, mj_core_schema } from '../config.js';
57
+ import { apiKey as callbackAPIKey, AskSkipInfo, baseUrl, publicUrl, configInfo, graphqlPort, graphqlRootPath, mj_core_schema } from '../config.js';
58
58
  import mssql from 'mssql';
59
59
 
60
60
  import { registerEnumType } from 'type-graphql';
@@ -445,7 +445,9 @@ type BaseSkipRequest = {
445
445
  /** API key for the calling server */
446
446
  callingServerAPIKey: string,
447
447
  /** Access token for the calling server */
448
- callingServerAccessToken: string
448
+ callingServerAccessToken: string,
449
+ /** Email of the user making the request */
450
+ userEmail: string
449
451
  }
450
452
  /**
451
453
  * Resolver for Skip AI interactions
@@ -729,7 +731,7 @@ export class AskSkipResolver {
729
731
  const skipConfigInfo = configInfo.askSkip;
730
732
  LogStatus(` >>> HandleSimpleSkipLearningPostRequest Sending request to Skip API: ${skipConfigInfo.learningCycleURL}`);
731
733
 
732
- const response = await sendPostRequest(skipConfigInfo.learningCycleURL, input, true, null);
734
+ const response = await sendPostRequest(skipConfigInfo.learningCycleURL, input, true, this.buildSkipPostHeaders());
733
735
 
734
736
  if (response && response.length > 0) {
735
737
  // the last object in the response array is the final response from the Skip API
@@ -790,7 +792,7 @@ export class AskSkipResolver {
790
792
  LogStatus(` >>> HandleSimpleSkipChatPostRequest Sending request to Skip API: ${skipConfigInfo.chatURL}`);
791
793
 
792
794
  try {
793
- const response = await sendPostRequest(skipConfigInfo.chatURL, input, true, null);
795
+ const response = await sendPostRequest(skipConfigInfo.chatURL, input, true, this.buildSkipPostHeaders());
794
796
 
795
797
  if (response && response.length > 0) {
796
798
  // the last object in the response array is the final response from the Skip API
@@ -1054,6 +1056,7 @@ cycle.`);
1054
1056
  queries,
1055
1057
  notes,
1056
1058
  noteTypes,
1059
+ userEmail: contextUser.Email,
1057
1060
  requests,
1058
1061
  accessToken,
1059
1062
  organizationID: skipConfigInfo.orgID,
@@ -1062,7 +1065,7 @@ cycle.`);
1062
1065
  // Favors public URL for conciseness or when behind a proxy for local development
1063
1066
  // otherwise uses base URL and GraphQL port/path from configuration
1064
1067
  callingServerURL: accessToken ? (publicUrl || `${baseUrl}:${graphqlPort}${graphqlRootPath}`) : undefined,
1065
- callingServerAPIKey: accessToken ? apiKey : undefined,
1068
+ callingServerAPIKey: accessToken ? callbackAPIKey : undefined,
1066
1069
  callingServerAccessToken: accessToken ? accessToken.Token : undefined
1067
1070
  };
1068
1071
  }
@@ -2459,7 +2462,7 @@ cycle.`);
2459
2462
  skipConfigInfo.chatURL,
2460
2463
  input,
2461
2464
  true,
2462
- null,
2465
+ this.buildSkipPostHeaders(),
2463
2466
  (message: {
2464
2467
  type: string;
2465
2468
  value: {
@@ -2605,6 +2608,12 @@ cycle.`);
2605
2608
  }
2606
2609
  }
2607
2610
 
2611
+ protected buildSkipPostHeaders(): { [key: string]: string } {
2612
+ return {
2613
+ 'x-api-key': configInfo.askSkip?.apiKey ?? '',
2614
+ };
2615
+ }
2616
+
2608
2617
  /**
2609
2618
  * Publishes a status update message to the user based on the Skip API response
2610
2619
  * Provides feedback about what phase of processing is happening