@memberjunction/server 4.2.0 → 4.3.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.
@@ -59681,6 +59681,14 @@ export class MJSchemaInfo_ {
59681
59681
  @Field({nullable: true})
59682
59682
  Description?: string;
59683
59683
 
59684
+ @Field({nullable: true, description: `Optional prefix to prepend to entity names generated for this schema. For example, setting this to "Committees: " would result in entity names like "Committees: Individuals". Can be overridden by mj.config.cjs NameRulesBySchema settings.`})
59685
+ @MaxLength(50)
59686
+ EntityNamePrefix?: string;
59687
+
59688
+ @Field({nullable: true, description: `Optional suffix to append to entity names generated for this schema. Can be overridden by mj.config.cjs NameRulesBySchema settings.`})
59689
+ @MaxLength(50)
59690
+ EntityNameSuffix?: string;
59691
+
59684
59692
  }
59685
59693
 
59686
59694
  //****************************************************************************
@@ -59705,6 +59713,12 @@ export class CreateMJSchemaInfoInput {
59705
59713
 
59706
59714
  @Field({ nullable: true })
59707
59715
  Description: string | null;
59716
+
59717
+ @Field({ nullable: true })
59718
+ EntityNamePrefix: string | null;
59719
+
59720
+ @Field({ nullable: true })
59721
+ EntityNameSuffix: string | null;
59708
59722
  }
59709
59723
 
59710
59724
 
@@ -59731,6 +59745,12 @@ export class UpdateMJSchemaInfoInput {
59731
59745
  @Field({ nullable: true })
59732
59746
  Description?: string | null;
59733
59747
 
59748
+ @Field({ nullable: true })
59749
+ EntityNamePrefix?: string | null;
59750
+
59751
+ @Field({ nullable: true })
59752
+ EntityNameSuffix?: string | null;
59753
+
59734
59754
  @Field(() => [KeyValuePairInput], { nullable: true })
59735
59755
  OldValues___?: KeyValuePairInput[];
59736
59756
  }
package/src/index.ts CHANGED
@@ -91,6 +91,7 @@ export * from './resolvers/MCPResolver.js';
91
91
  export * from './resolvers/ActionResolver.js';
92
92
  export * from './resolvers/EntityCommunicationsResolver.js';
93
93
  export * from './resolvers/EntityResolver.js';
94
+ export * from './resolvers/ISAEntityResolver.js';
94
95
  export * from './resolvers/FileCategoryResolver.js';
95
96
  export * from './resolvers/FileResolver.js';
96
97
  export * from './resolvers/InfoResolver.js';
@@ -0,0 +1,96 @@
1
+ import { EntityInfo, IEntityDataProvider, Metadata, UserInfo } from '@memberjunction/core';
2
+ import { Arg, Ctx, Field, ObjectType, Query, Resolver } from 'type-graphql';
3
+ import { AppContext } from '../types.js';
4
+ import { GetReadOnlyProvider } from '../util.js';
5
+
6
+ /**
7
+ * Result type for the IS-A child entity discovery query.
8
+ * Returns the name of the child entity type that has a record matching
9
+ * the given parent entity's primary key, or null if no child exists.
10
+ */
11
+ @ObjectType()
12
+ export class ISAChildEntityResult {
13
+ @Field(() => Boolean)
14
+ Success: boolean;
15
+
16
+ @Field(() => String, { nullable: true })
17
+ ChildEntityName?: string;
18
+
19
+ @Field(() => String, { nullable: true })
20
+ ErrorMessage?: string;
21
+ }
22
+
23
+ /**
24
+ * Resolver for IS-A entity hierarchy discovery.
25
+ *
26
+ * Provides a GraphQL endpoint for client-side code to discover child entity
27
+ * records in an IS-A hierarchy. This enables bidirectional chain construction
28
+ * where a loaded entity discovers its more-derived child type.
29
+ */
30
+ @Resolver(ISAChildEntityResult)
31
+ export class ISAEntityResolver {
32
+ /**
33
+ * Discovers which IS-A child entity, if any, has a record with the given
34
+ * primary key value. The server executes a single UNION ALL query across
35
+ * all child entity tables for maximum efficiency.
36
+ *
37
+ * @param EntityName The parent entity name to check children for
38
+ * @param RecordID The primary key value to search for in child tables
39
+ * @returns The child entity name if found, or null with Success=true if no child exists
40
+ */
41
+ @Query(() => ISAChildEntityResult)
42
+ async FindISAChildEntity(
43
+ @Arg('EntityName', () => String) EntityName: string,
44
+ @Arg('RecordID', () => String) RecordID: string,
45
+ @Ctx() { providers, userPayload }: AppContext
46
+ ): Promise<ISAChildEntityResult> {
47
+ try {
48
+ const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
49
+ const md = new Metadata();
50
+ const entityInfo = md.Entities.find(e => e.Name === EntityName);
51
+
52
+ if (!entityInfo) {
53
+ return {
54
+ Success: false,
55
+ ErrorMessage: `Entity '${EntityName}' not found`
56
+ };
57
+ }
58
+
59
+ if (!entityInfo.IsParentType) {
60
+ return { Success: true };
61
+ }
62
+
63
+ // Cast to IEntityDataProvider to access the optional FindISAChildEntity method
64
+ const entityProvider = provider as unknown as IEntityDataProvider;
65
+ if (!entityProvider.FindISAChildEntity) {
66
+ return {
67
+ Success: false,
68
+ ErrorMessage: 'Provider does not support FindISAChildEntity'
69
+ };
70
+ }
71
+
72
+ const result = await entityProvider.FindISAChildEntity(
73
+ entityInfo,
74
+ RecordID,
75
+ userPayload?.userRecord
76
+ );
77
+
78
+ if (result) {
79
+ return {
80
+ Success: true,
81
+ ChildEntityName: result.ChildEntityName
82
+ };
83
+ }
84
+
85
+ return { Success: true };
86
+ }
87
+ catch (e) {
88
+ return {
89
+ Success: false,
90
+ ErrorMessage: e instanceof Error ? e.message : String(e)
91
+ };
92
+ }
93
+ }
94
+ }
95
+
96
+ export default ISAEntityResolver;