@memberjunction/server 0.9.93 → 0.9.95

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 (47) hide show
  1. package/build.log.json +6 -0
  2. package/dist/generated/generated.js +18854 -0
  3. package/dist/generated/generated.js.map +1 -0
  4. package/dist/generic/PushStatusResolver.js +59 -0
  5. package/dist/generic/PushStatusResolver.js.map +1 -0
  6. package/dist/generic/ResolverBase.js +208 -0
  7. package/dist/generic/ResolverBase.js.map +1 -0
  8. package/dist/generic/RunViewResolver.js +401 -0
  9. package/dist/generic/RunViewResolver.js.map +1 -0
  10. package/dist/index.js +20 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/resolvers/AskSkipResolver.js +247 -0
  13. package/dist/resolvers/AskSkipResolver.js.map +1 -0
  14. package/dist/resolvers/ColorResolver.js +94 -0
  15. package/dist/resolvers/ColorResolver.js.map +1 -0
  16. package/dist/resolvers/DatasetResolver.js +168 -0
  17. package/dist/resolvers/DatasetResolver.js.map +1 -0
  18. package/dist/resolvers/EntityRecordNameResolver.js +111 -0
  19. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -0
  20. package/dist/resolvers/EntityResolver.js +60 -0
  21. package/dist/resolvers/EntityResolver.js.map +1 -0
  22. package/dist/resolvers/MergeRecordsResolver.js +256 -0
  23. package/dist/resolvers/MergeRecordsResolver.js.map +1 -0
  24. package/dist/resolvers/ReportResolver.js +74 -0
  25. package/dist/resolvers/ReportResolver.js.map +1 -0
  26. package/dist/resolvers/UserFavoriteResolver.js +185 -0
  27. package/dist/resolvers/UserFavoriteResolver.js.map +1 -0
  28. package/dist/resolvers/UserResolver.js +70 -0
  29. package/dist/resolvers/UserResolver.js.map +1 -0
  30. package/dist/resolvers/UserViewResolver.js +102 -0
  31. package/dist/resolvers/UserViewResolver.js.map +1 -0
  32. package/package.json +6 -6
  33. package/src/generated/generated.ts +13928 -0
  34. package/src/generic/PushStatusResolver.ts +41 -0
  35. package/src/generic/ResolverBase.ts +285 -0
  36. package/src/generic/RunViewResolver.ts +350 -0
  37. package/src/index.ts +31 -3
  38. package/src/resolvers/AskSkipResolver.ts +237 -0
  39. package/src/resolvers/ColorResolver.ts +72 -0
  40. package/src/resolvers/DatasetResolver.ts +114 -0
  41. package/src/resolvers/EntityRecordNameResolver.ts +73 -0
  42. package/src/resolvers/EntityResolver.ts +34 -0
  43. package/src/resolvers/MergeRecordsResolver.ts +178 -0
  44. package/src/resolvers/ReportResolver.ts +56 -0
  45. package/src/resolvers/UserFavoriteResolver.ts +123 -0
  46. package/src/resolvers/UserResolver.ts +29 -0
  47. package/src/resolvers/UserViewResolver.ts +63 -0
@@ -0,0 +1,178 @@
1
+ import { LogError, Metadata } from '@memberjunction/core';
2
+ import { Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, PubSub, PubSubEngine, Query, Resolver } from 'type-graphql';
3
+ import { AppContext } from '../types';
4
+
5
+ @ObjectType()
6
+ export class EntityDependencyResult {
7
+ @Field(() => String)
8
+ EntityName: string; // required
9
+
10
+ @Field(() => String)
11
+ RelatedEntityName: string; // required
12
+
13
+ @Field(() => String)
14
+ FieldName: string; // required
15
+ }
16
+
17
+ @Resolver(EntityDependencyResult)
18
+ export class EntityDependencyResolver {
19
+ @Query(() => [EntityDependencyResult])
20
+ async GetEntityDependencies(
21
+ @Arg('entityName', () => String) entityName: string,
22
+ @Arg('recordId', () => Int) recordId: number,
23
+ @Ctx() { dataSource, userPayload }: AppContext,
24
+ @PubSub() pubSub: PubSubEngine
25
+ ) {
26
+ try {
27
+ const md = new Metadata();
28
+ return md.GetEntityDependencies(entityName);
29
+ }
30
+ catch (err) {
31
+ LogError(err);
32
+ throw new Error(err.message);
33
+ }
34
+ }
35
+
36
+ }
37
+
38
+
39
+ @ObjectType()
40
+ export class RecordDependencyResult {
41
+ @Field(() => String)
42
+ EntityName: string; // required
43
+
44
+ @Field(() => String)
45
+ RelatedEntityName: string; // required
46
+
47
+ @Field(() => String)
48
+ FieldName: string; // required
49
+
50
+ @Field(() => Int)
51
+ RecordID: number;
52
+ }
53
+
54
+ @Resolver(RecordDependencyResult)
55
+ export class RecordDependencyResolver {
56
+ @Query(() => [RecordDependencyResult])
57
+ async GetRecordDependencies(
58
+ @Arg('entityName', () => String) entityName: string,
59
+ @Arg('recordId', () => Int) recordId: number,
60
+ @Ctx() { dataSource, userPayload }: AppContext,
61
+ @PubSub() pubSub: PubSubEngine
62
+ ) {
63
+ try {
64
+ const md = new Metadata();
65
+ const result = await md.GetRecordDependencies(entityName, recordId)
66
+ return result;
67
+ }
68
+ catch (e) {
69
+ LogError(e);
70
+ throw e;
71
+ }
72
+ }
73
+ }
74
+
75
+ @InputType()
76
+ class FieldMapping {
77
+ @Field(() => String)
78
+ FieldName: string;
79
+
80
+ @Field(() => String)
81
+ Value: string;
82
+ }
83
+
84
+ @ObjectType()
85
+ class FieldMappingOutput {
86
+ @Field(() => String)
87
+ FieldName: string;
88
+
89
+ @Field(() => String)
90
+ Value: string;
91
+ }
92
+
93
+ @InputType()
94
+ export class RecordMergeRequest {
95
+ @Field(() => String)
96
+ EntityName: string;
97
+
98
+ @Field(() => String)
99
+ SurvivingRecordPrimaryKeyValue: string;
100
+
101
+ @Field(() => [Int])
102
+ RecordsToMerge: number[];
103
+
104
+ @Field(() => [FieldMapping], { nullable: true })
105
+ FieldMap?: FieldMapping[];
106
+ }
107
+
108
+ @ObjectType()
109
+ export class RecordMergeRequestOutput {
110
+ @Field(() => String)
111
+ EntityName: string;
112
+
113
+ @Field(() => Int)
114
+ SurvivingRecordID: number;
115
+
116
+ @Field(() => [Int])
117
+ RecordsToMerge: number[];
118
+
119
+ @Field(() => [FieldMappingOutput], { nullable: true })
120
+ FieldMap?: FieldMappingOutput[];
121
+ }
122
+
123
+
124
+ @ObjectType()
125
+ export class RecordMergeDetailResult {
126
+ @Field(() => Int)
127
+ RecordID: number;
128
+
129
+ @Field(() => Boolean)
130
+ Success: boolean;
131
+
132
+ @Field(() => Int, {nullable: true})
133
+ RecordMergeDeletionLogID?: number;
134
+
135
+ @Field(() => String, {nullable: true})
136
+ Message?: string;
137
+ }
138
+
139
+ @ObjectType()
140
+ export class RecordMergeResult {
141
+ @Field(() => Boolean)
142
+ Success: boolean;
143
+
144
+ @Field(() => String, {nullable: true})
145
+ OverallStatus: string;
146
+
147
+ @Field(() => Int, {nullable: true})
148
+ RecordMergeLogID: number;
149
+
150
+ @Field(() => [RecordMergeDetailResult])
151
+ RecordStatus: RecordMergeDetailResult[];
152
+
153
+ @Field(() => RecordMergeRequestOutput)
154
+ Request: RecordMergeRequestOutput;
155
+ }
156
+
157
+ @Resolver(RecordMergeResult)
158
+ export class RecordMergeResolver {
159
+ @Mutation(() => RecordMergeResult)
160
+ async MergeRecords(
161
+ @Arg('request', () => RecordMergeRequest) request: RecordMergeRequest,
162
+ @Ctx() { dataSource, userPayload }: AppContext,
163
+ @PubSub() pubSub: PubSubEngine
164
+ ) {
165
+ try {
166
+ const md = new Metadata();
167
+ const result = await md.MergeRecords(request, userPayload.userRecord);
168
+ return result;
169
+ }
170
+ catch (e) {
171
+ LogError(e);
172
+ throw e;
173
+ }
174
+ }
175
+ }
176
+
177
+
178
+ export default EntityDependencyResolver;
@@ -0,0 +1,56 @@
1
+ import { RunReport } from '@memberjunction/core';
2
+ import { Arg, Ctx, Field, Int, ObjectType, Query, Resolver } from 'type-graphql';
3
+ import { AppContext } from '../types';
4
+
5
+ @ObjectType()
6
+ export class RunReportResultType {
7
+ @Field()
8
+ ReportID: number;
9
+
10
+ @Field()
11
+ Success: boolean;
12
+
13
+ @Field()
14
+ Results: string;
15
+
16
+ @Field()
17
+ RowCount: number;
18
+
19
+ @Field()
20
+ ExecutionTime: number;
21
+
22
+ @Field()
23
+ ErrorMessage: string;
24
+ }
25
+
26
+ @Resolver(RunReportResultType)
27
+ export class ReportResolver {
28
+ @Query(() => RunReportResultType)
29
+ async GetReportData(@Arg('ReportID', () => Int) ReportID: number, @Ctx() {}: AppContext): Promise<RunReportResultType> {
30
+ const runReport = new RunReport();
31
+ const result = await runReport.RunReport({ ReportID: ReportID });
32
+ return {
33
+ ReportID: ReportID,
34
+ Success: result.Success,
35
+ Results: JSON.stringify(result.Results),
36
+ RowCount: result.RowCount,
37
+ ExecutionTime: result.ExecutionTime,
38
+ ErrorMessage: result.ErrorMessage,
39
+ };
40
+ // // run the sql and return the data
41
+ // const sqlReport = "SELECT GeneratedSQLText FROM vwReports WHERE ID = " + ReportID;
42
+ // const reportInfo = await dataSource.query(sqlReport);
43
+ // if (reportInfo && reportInfo.length > 0) {
44
+ // const start = new Date().getTime();
45
+ // const sql = reportInfo[0].GeneratedSQLText;
46
+ // const result = await dataSource.query(sql);
47
+ // const end = new Date().getTime();
48
+ // if (result)
49
+ // return {Success: true, ReportID: ReportID, Results: JSON.stringify(result), RowCount: result.length, ExecutionTime: end-start, ErrorMessage: ''};
50
+ // else
51
+ // return {Success: false, ReportID: ReportID, Results: '[]', RowCount: 0, ExecutionTime: end - start, ErrorMessage: 'Error running report SQL'};
52
+ // }
53
+ // else
54
+ // return {Success: false, ReportID: ReportID, Results: '[]', RowCount: 0, ExecutionTime: 0, ErrorMessage: 'Report not found'};
55
+ }
56
+ }
@@ -0,0 +1,123 @@
1
+ import { Metadata } from '@memberjunction/core';
2
+ import { AppContext, Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, Query, Resolver } from '@memberjunction/server';
3
+ import { UserCache } from '@memberjunction/sqlserver-dataprovider';
4
+ import { UserFavoriteEntity } from '@memberjunction/core-entities';
5
+
6
+ import { UserFavorite_, UserFavoriteResolverBase } from '../generated/generated';
7
+
8
+ //****************************************************************************
9
+ // INPUT TYPE for User Favorite Queries
10
+ //****************************************************************************
11
+ @InputType()
12
+ export class UserFavoriteSearchParams {
13
+ @Field(() => Int)
14
+ EntityID: number;
15
+
16
+ @Field(() => String)
17
+ PrimaryKeyValue: string;
18
+
19
+ @Field(() => Int)
20
+ UserID: number;
21
+ }
22
+
23
+ @InputType()
24
+ export class UserFavoriteSetParams {
25
+ @Field(() => Int)
26
+ EntityID: number;
27
+
28
+ @Field(() => String)
29
+ PrimaryKeyValue: string;
30
+
31
+ @Field(() => Int)
32
+ UserID: number;
33
+
34
+ @Field(() => Boolean)
35
+ IsFavorite: boolean;
36
+ }
37
+
38
+ @ObjectType()
39
+ export class UserFavoriteResult {
40
+ @Field(() => Int)
41
+ EntityID: number;
42
+
43
+ @Field(() => String)
44
+ PrimaryKeyValue: string;
45
+
46
+ @Field(() => Int)
47
+ UserID: number;
48
+
49
+ @Field(() => Boolean)
50
+ IsFavorite: boolean;
51
+
52
+ @Field(() => Boolean)
53
+ Success: boolean;
54
+ }
55
+
56
+ @Resolver(UserFavorite_)
57
+ export class UserFavoriteResolver extends UserFavoriteResolverBase {
58
+ @Query(() => [UserFavorite_])
59
+ async UserFavoritesByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { dataSource }: AppContext) {
60
+ return await this.findBy(dataSource, 'User Favorites', { UserID });
61
+ }
62
+
63
+ @Query(() => [UserFavorite_])
64
+ async UserFavoriteSearchByParams(@Arg('params', () => Int) params: UserFavoriteSearchParams, @Ctx() { dataSource }: AppContext) {
65
+ return await this.findBy(dataSource, 'User Favorites', params);
66
+ }
67
+
68
+ @Query(() => UserFavoriteResult)
69
+ async GetRecordFavoriteStatus(@Arg('params', () => UserFavoriteSearchParams) params: UserFavoriteSearchParams, @Ctx() {}: AppContext) {
70
+ const md = new Metadata();
71
+ const e = md.Entities.find((e) => e.ID === params.EntityID);
72
+ if (e)
73
+ return {
74
+ EntityID: params.EntityID,
75
+ UserID: params.UserID,
76
+ PrimaryKeyValue: params.PrimaryKeyValue,
77
+ IsFavorite: await md.GetRecordFavoriteStatus(params.UserID, e.Name, params.PrimaryKeyValue),
78
+ Success: true,
79
+ };
80
+ else throw new Error(`Entity ID:${params.EntityID} not found`);
81
+ }
82
+
83
+ @Mutation(() => UserFavoriteResult)
84
+ SetRecordFavoriteStatus(@Arg('params', () => UserFavoriteSetParams) params: UserFavoriteSetParams, @Ctx() { userPayload }: AppContext) {
85
+ const md = new Metadata();
86
+ const e = md.Entities.find((e) => e.ID === params.EntityID);
87
+ const u = UserCache.Users.find((u) => u.ID === userPayload.userRecord.ID);
88
+ if (e) {
89
+ md.SetRecordFavoriteStatus(params.UserID, e.Name, params.PrimaryKeyValue, params.IsFavorite, u);
90
+ return {
91
+ Success: true,
92
+ EntityID: params.EntityID,
93
+ UserID: params.UserID,
94
+ PrimaryKeyValue: params.PrimaryKeyValue,
95
+ IsFavorite: params.IsFavorite,
96
+ };
97
+ } else throw new Error(`Entity ID:${params.EntityID} not found`);
98
+ }
99
+
100
+ @Mutation(() => UserFavorite_)
101
+ async AddUserFavorite(
102
+ @Arg('input', () => UserFavoriteSearchParams) input: UserFavoriteSearchParams,
103
+ @Ctx() { dataSource, userPayload }: AppContext
104
+ ) {
105
+ const [existing] = await this.findBy(dataSource, 'User Favorites', input);
106
+ if (existing)
107
+ return existing;
108
+
109
+ const md = new Metadata();
110
+
111
+ const ufEntity = <UserFavoriteEntity>await md.GetEntityObject('User Favorites', userPayload.userRecord);
112
+ ufEntity.NewRecord();
113
+ ufEntity.EntityID = input.EntityID;
114
+ ufEntity.RecordID = input.PrimaryKeyValue;
115
+ ufEntity.UserID = input.UserID;
116
+ if (await ufEntity.Save())
117
+ return ufEntity.GetAll();
118
+ else
119
+ throw new Error('Error saving user favorite');
120
+ }
121
+ }
122
+
123
+ export default UserFavoriteResolver;
@@ -0,0 +1,29 @@
1
+ import { AppContext, Arg, Ctx, Int, Query, Resolver } from '@memberjunction/server';
2
+ import { User_, UserResolverBase } from '../generated/generated';
3
+
4
+ @Resolver(User_)
5
+ export class UserResolver extends UserResolverBase {
6
+ @Query(() => User_)
7
+ async CurrentUser(@Ctx() { dataSource, userPayload }: AppContext) {
8
+ return await this.UserByEmail(userPayload.email, { dataSource, userPayload });
9
+ }
10
+
11
+ @Query(() => User_)
12
+ async UserByID(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource }: AppContext) {
13
+ return super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { ID }));
14
+ }
15
+
16
+ @Query(() => User_)
17
+ async UserByEmployeeID(@Arg('EmployeeID', () => Int) EmployeeID: number, @Ctx() { dataSource }: AppContext) {
18
+ return super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { EmployeeID }));
19
+ }
20
+
21
+ @Query(() => User_)
22
+ async UserByEmail(@Arg('Email', () => String) Email: string, @Ctx() { dataSource }: AppContext) {
23
+ // const searchEmail = userEmailMap[Email] ?? Email;
24
+ const searchEmail = Email;
25
+ const returnVal = super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { Email: searchEmail }));
26
+ return returnVal;
27
+ }
28
+ }
29
+ export default UserResolver;
@@ -0,0 +1,63 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Metadata } from '@memberjunction/core';
3
+ import { AppContext, Arg, Ctx, Int, Query, Resolver, UserPayload } from '@memberjunction/server';
4
+ import { DataSource } from 'typeorm';
5
+ import { UserView_, UserViewResolverBase } from '../generated/generated';
6
+ import { UserResolver } from './UserResolver';
7
+
8
+ @Resolver(UserView_)
9
+ export class UserViewResolver extends UserViewResolverBase {
10
+ @Query(() => [UserView_])
11
+ async UserViewsByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { dataSource }: AppContext) {
12
+ return await this.findBy(dataSource, 'User Views', { UserID });
13
+ }
14
+
15
+ @Query(() => [UserView_])
16
+ async DefaultViewByUserAndEntity(
17
+ @Arg('UserID', () => Int) UserID: number,
18
+ @Arg('EntityID', () => Int) EntityID: number,
19
+ @Ctx() { dataSource }: AppContext
20
+ ) {
21
+ return await this.findBy(dataSource, 'User Views', { UserID, EntityID, IsDefault: true });
22
+ }
23
+
24
+ @Query(() => [UserView_])
25
+ async CurrentUserDefaultViewByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() { dataSource, userPayload }: AppContext) {
26
+ return await this.findBy(dataSource, 'User Views', {
27
+ UserID: await this.getCurrentUserID(dataSource, userPayload),
28
+ EntityID,
29
+ IsDefault: true,
30
+ });
31
+ }
32
+
33
+ protected async getCurrentUserID(dataSource: DataSource, userPayload: UserPayload): Promise<number> {
34
+ const userResolver = new UserResolver();
35
+ const user = await userResolver.UserByEmail(userPayload.email, { dataSource, userPayload });
36
+ return user.ID;
37
+ }
38
+
39
+ @Query(() => [UserView_])
40
+ async CurrentUserUserViewsByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() { dataSource, userPayload }: AppContext) {
41
+ return this.findBy(dataSource, 'User Views', { UserID: await this.getCurrentUserID(dataSource, userPayload), EntityID });
42
+ }
43
+
44
+ @Query(() => [UserView_])
45
+ async UpdateWhereClause(@Arg('ID', () => Int) ID: number, @Ctx() { userPayload }: AppContext) {
46
+ // in this query we want to update the uesrView record in the DB with a new where clause
47
+ // this should normally not be a factor but we have this exposed in the GraphQL API so that
48
+ // a dev can force the update if desired from the client. The normal path is just to update
49
+ // filter state which in turn will be used to update the where clause in the entity sub-class.
50
+ const md = new Metadata();
51
+ const u = this.GetUserFromPayload(userPayload);
52
+ const viewEntity = await md.GetEntityObject('User Views', u);
53
+ await viewEntity.Load(ID);
54
+ viewEntity.UpdateWhereClause();
55
+ if (await viewEntity.Save()) {
56
+ return viewEntity.GetAll();
57
+ } else {
58
+ throw new Error('Failed to update where clause');
59
+ }
60
+ }
61
+ }
62
+
63
+ export default UserViewResolver;