@memberjunction/server 0.9.238 → 0.9.241

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.
@@ -0,0 +1,21 @@
1
+ import { AppContext, PubSubEngine } from '@memberjunction/server';
2
+ import { CreateFileInput, FileResolver as FileResolverBase, File_ } from '../generated/generated';
3
+ export declare class CreateUploadURLInput {
4
+ FileID: number;
5
+ }
6
+ export declare class CreateFilePayload {
7
+ File: File_;
8
+ UploadUrl: string;
9
+ }
10
+ export declare class FileExt extends File_ {
11
+ DownloadUrl: string;
12
+ }
13
+ export declare class FileResolver extends FileResolverBase {
14
+ CreateFile(input: CreateFileInput, { dataSource, userPayload }: AppContext, pubSub: PubSubEngine): Promise<{
15
+ File: {};
16
+ UploadUrl: string;
17
+ }>;
18
+ DownloadUrl(file: File_, { userPayload }: AppContext): Promise<string>;
19
+ DeleteFile(ID: number, { dataSource, userPayload }: AppContext, pubSub: PubSubEngine): Promise<{}>;
20
+ }
21
+ //# sourceMappingURL=FileResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/FileResolver.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EAUV,YAAY,EAGb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,YAAY,IAAI,gBAAgB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAElG,qBACa,oBAAoB;IAE/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBACa,iBAAiB;IAE5B,IAAI,EAAE,KAAK,CAAC;IAEZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBACa,OAAQ,SAAQ,KAAK;IAEhC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBACa,YAAa,SAAQ,gBAAgB;IAE1C,UAAU,CACuB,KAAK,EAAE,eAAe,EACpD,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,UAAU,EACpC,MAAM,EAAE,YAAY;;;;IA2B1B,WAAW,CAAS,IAAI,EAAE,KAAK,EAAS,EAAE,WAAW,EAAE,EAAE,UAAU;IAanE,UAAU,CAAuB,EAAE,EAAE,MAAM,EAAS,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,UAAU,EAAY,MAAM,EAAE,YAAY;CAiBlI"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.FileResolver = exports.FileExt = exports.CreateFilePayload = exports.CreateUploadURLInput = void 0;
16
+ const core_1 = require("@memberjunction/core");
17
+ const server_1 = require("@memberjunction/server");
18
+ const storage_1 = require("@memberjunction/storage");
19
+ const generated_1 = require("../generated/generated");
20
+ let CreateUploadURLInput = class CreateUploadURLInput {
21
+ };
22
+ exports.CreateUploadURLInput = CreateUploadURLInput;
23
+ __decorate([
24
+ (0, server_1.Field)(() => server_1.Int),
25
+ __metadata("design:type", Number)
26
+ ], CreateUploadURLInput.prototype, "FileID", void 0);
27
+ exports.CreateUploadURLInput = CreateUploadURLInput = __decorate([
28
+ (0, server_1.InputType)()
29
+ ], CreateUploadURLInput);
30
+ let CreateFilePayload = class CreateFilePayload {
31
+ };
32
+ exports.CreateFilePayload = CreateFilePayload;
33
+ __decorate([
34
+ (0, server_1.Field)(() => generated_1.File_),
35
+ __metadata("design:type", generated_1.File_)
36
+ ], CreateFilePayload.prototype, "File", void 0);
37
+ __decorate([
38
+ (0, server_1.Field)(() => String),
39
+ __metadata("design:type", String)
40
+ ], CreateFilePayload.prototype, "UploadUrl", void 0);
41
+ exports.CreateFilePayload = CreateFilePayload = __decorate([
42
+ (0, server_1.ObjectType)()
43
+ ], CreateFilePayload);
44
+ let FileExt = class FileExt extends generated_1.File_ {
45
+ };
46
+ exports.FileExt = FileExt;
47
+ __decorate([
48
+ (0, server_1.Field)(() => String),
49
+ __metadata("design:type", String)
50
+ ], FileExt.prototype, "DownloadUrl", void 0);
51
+ exports.FileExt = FileExt = __decorate([
52
+ (0, server_1.ObjectType)()
53
+ ], FileExt);
54
+ let FileResolver = class FileResolver extends generated_1.FileResolver {
55
+ async CreateFile(input, { dataSource, userPayload }, pubSub) {
56
+ const md = new core_1.Metadata();
57
+ const userInfo = this.GetUserFromPayload(userPayload);
58
+ const providerEntity = await md.GetEntityObject('File Storage Providers', userInfo);
59
+ const fileRecord = (await super.CreateFile({ ...input, Status: 'Pending' }, { dataSource, userPayload }, pubSub));
60
+ if (!fileRecord) {
61
+ return null;
62
+ }
63
+ const { updatedInput, UploadUrl } = await (0, storage_1.createUploadUrl)(providerEntity, fileRecord);
64
+ const fileEntity = await new core_1.Metadata().GetEntityObject('Files', userInfo);
65
+ fileEntity.LoadFromData(input);
66
+ fileEntity.SetMany(updatedInput);
67
+ await fileEntity.Save();
68
+ const File = fileEntity.GetAll();
69
+ return { File, UploadUrl };
70
+ }
71
+ async DownloadUrl(file, { userPayload }) {
72
+ const md = new core_1.Metadata();
73
+ const providerEntity = await md.GetEntityObject('File Storage Providers', this.GetUserFromPayload(userPayload));
74
+ const url = await (0, storage_1.createDownloadUrl)(providerEntity, file.ProviderKey ?? file.ID);
75
+ return url;
76
+ }
77
+ async DeleteFile(ID, { dataSource, userPayload }, pubSub) {
78
+ const md = new core_1.Metadata();
79
+ const userInfo = this.GetUserFromPayload(userPayload);
80
+ const entityObject = await md.GetEntityObject('Files', userInfo);
81
+ await entityObject.Load(ID);
82
+ if (!entityObject) {
83
+ return null;
84
+ }
85
+ if (entityObject.Status === 'Uploaded') {
86
+ const providerEntity = await md.GetEntityObject('File Storage Providers', userInfo);
87
+ await (0, storage_1.deleteObject)(providerEntity, entityObject.ProviderKey ?? entityObject.ID);
88
+ }
89
+ return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
90
+ }
91
+ };
92
+ exports.FileResolver = FileResolver;
93
+ __decorate([
94
+ (0, server_1.Mutation)(() => CreateFilePayload),
95
+ __param(0, (0, server_1.Arg)('input', () => generated_1.CreateFileInput)),
96
+ __param(1, (0, server_1.Ctx)()),
97
+ __param(2, (0, server_1.PubSub)()),
98
+ __metadata("design:type", Function),
99
+ __metadata("design:paramtypes", [generated_1.CreateFileInput, Object, server_1.PubSubEngine]),
100
+ __metadata("design:returntype", Promise)
101
+ ], FileResolver.prototype, "CreateFile", null);
102
+ __decorate([
103
+ (0, server_1.FieldResolver)(() => String),
104
+ __param(0, (0, server_1.Root)()),
105
+ __param(1, (0, server_1.Ctx)()),
106
+ __metadata("design:type", Function),
107
+ __metadata("design:paramtypes", [generated_1.File_, Object]),
108
+ __metadata("design:returntype", Promise)
109
+ ], FileResolver.prototype, "DownloadUrl", null);
110
+ __decorate([
111
+ (0, server_1.Mutation)(() => generated_1.File_),
112
+ __param(0, (0, server_1.Arg)('ID', () => server_1.Int)),
113
+ __param(1, (0, server_1.Ctx)()),
114
+ __param(2, (0, server_1.PubSub)()),
115
+ __metadata("design:type", Function),
116
+ __metadata("design:paramtypes", [Number, Object, server_1.PubSubEngine]),
117
+ __metadata("design:returntype", Promise)
118
+ ], FileResolver.prototype, "DeleteFile", null);
119
+ exports.FileResolver = FileResolver = __decorate([
120
+ (0, server_1.Resolver)(generated_1.File_)
121
+ ], FileResolver);
122
+ //# sourceMappingURL=FileResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileResolver.js","sourceRoot":"","sources":["../../src/resolvers/FileResolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/server",
3
- "version": "0.9.238",
3
+ "version": "0.9.241",
4
4
  "description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -21,16 +21,17 @@
21
21
  "dependencies": {
22
22
  "@apollo/server": "^4.9.1",
23
23
  "@graphql-tools/utils": "^10.0.1",
24
- "@memberjunction/ai": "^0.9.160",
25
- "@memberjunction/aiengine": "^0.9.58",
26
- "@memberjunction/core": "^0.9.172",
27
- "@memberjunction/core-entities": "^0.9.157",
28
- "@memberjunction/data-context": "^0.9.45",
29
- "@memberjunction/data-context-server": "^0.9.41",
30
- "@memberjunction/global": "^0.9.153",
31
- "@memberjunction/queue": "^0.9.179",
32
- "@memberjunction/sqlserver-dataprovider": "^0.9.195",
33
- "@memberjunction/skip-types": "^0.9.70",
24
+ "@memberjunction/ai": "^0.9.162",
25
+ "@memberjunction/aiengine": "^0.9.61",
26
+ "@memberjunction/core": "^0.9.175",
27
+ "@memberjunction/core-entities": "^0.9.160",
28
+ "@memberjunction/data-context": "^0.9.48",
29
+ "@memberjunction/data-context-server": "^0.9.44",
30
+ "@memberjunction/global": "^0.9.155",
31
+ "@memberjunction/storage": "^0.9.5",
32
+ "@memberjunction/queue": "^0.9.182",
33
+ "@memberjunction/sqlserver-dataprovider": "^0.9.198",
34
+ "@memberjunction/skip-types": "^0.9.73",
34
35
  "@types/cors": "^2.8.13",
35
36
  "@types/jsonwebtoken": "^8.5.9",
36
37
  "@types/node": "^18.11.14",
package/src/context.ts CHANGED
@@ -110,7 +110,10 @@ export const contextFunction =
110
110
  const userPayload = await getUserPayload(bearerToken, sessionId, dataSource, requestDomain?.hostname ? requestDomain.hostname : undefined);
111
111
 
112
112
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
- console.log((req as any).body?.operationName);
113
+ const operationName: string| undefined = (req as any).body?.operationName;
114
+ if (operationName !== 'IntrospectionQuery') {
115
+ console.log({ operationName });
116
+ }
114
117
 
115
118
  return { dataSource, userPayload };
116
119
  };
@@ -2,7 +2,7 @@
2
2
  * ALL ENTITIES - TypeGraphQL Type Class Definition - AUTO GENERATED FILE
3
3
  * Generated Entities and Resolvers for Server
4
4
  *
5
- * GENERATED: 3/18/2024, 2:22:24 PM
5
+ * GENERATED: 3/21/2024, 5:44:24 PM
6
6
  *
7
7
  * >>> DO NOT MODIFY THIS FILE!!!!!!!!!!!!
8
8
  * >>> YOUR CHANGES WILL BE OVERWRITTEN
@@ -4012,6 +4012,9 @@ export class EntityRelationship_ {
4012
4012
  @Field(() => Int)
4013
4013
  EntityID: number;
4014
4014
 
4015
+ @Field(() => Int, {description: 'Used for display order in generated forms and in other places in the UI where relationships for an entity are shown'})
4016
+ Sequence: number;
4017
+
4015
4018
  @Field(() => Int)
4016
4019
  RelatedEntityID: number;
4017
4020
 
@@ -4117,6 +4120,9 @@ export class CreateEntityRelationshipInput {
4117
4120
  @Field(() => Int)
4118
4121
  EntityID: number;
4119
4122
 
4123
+ @Field(() => Int)
4124
+ Sequence: number;
4125
+
4120
4126
  @Field(() => Int)
4121
4127
  RelatedEntityID: number;
4122
4128
 
@@ -4163,6 +4169,9 @@ export class UpdateEntityRelationshipInput {
4163
4169
  @Field(() => Int)
4164
4170
  EntityID: number;
4165
4171
 
4172
+ @Field(() => Int)
4173
+ Sequence: number;
4174
+
4166
4175
  @Field(() => Int)
4167
4176
  RelatedEntityID: number;
4168
4177
 
@@ -14619,8 +14628,8 @@ export class Query_ {
14619
14628
  @Field({nullable: true})
14620
14629
  Description?: string;
14621
14630
 
14622
- @Field(() => Int)
14623
- CategoryID: number;
14631
+ @Field(() => Int, {nullable: true})
14632
+ CategoryID?: number;
14624
14633
 
14625
14634
  @Field({nullable: true})
14626
14635
  SQL?: string;
@@ -14646,9 +14655,9 @@ export class Query_ {
14646
14655
  @MaxLength(8)
14647
14656
  UpdatedAt: Date;
14648
14657
 
14649
- @Field()
14658
+ @Field({nullable: true})
14650
14659
  @MaxLength(100)
14651
- Category: string;
14660
+ Category?: string;
14652
14661
 
14653
14662
  @Field(() => [mj_core_schema_server_object_types.QueryField_])
14654
14663
  QueryFieldsArray: mj_core_schema_server_object_types.QueryField_[]; // Link to QueryFields
@@ -14672,7 +14681,7 @@ export class CreateQueryInput {
14672
14681
  @Field({ nullable: true })
14673
14682
  Description: string;
14674
14683
 
14675
- @Field(() => Int)
14684
+ @Field(() => Int, { nullable: true })
14676
14685
  CategoryID: number;
14677
14686
 
14678
14687
  @Field({ nullable: true })
@@ -14706,7 +14715,7 @@ export class UpdateQueryInput {
14706
14715
  @Field({ nullable: true })
14707
14716
  Description: string;
14708
14717
 
14709
- @Field(() => Int)
14718
+ @Field(() => Int, { nullable: true })
14710
14719
  CategoryID: number;
14711
14720
 
14712
14721
  @Field({ nullable: true })
@@ -17161,8 +17170,8 @@ export class ReportCategory_ {
17161
17170
  @Field({nullable: true})
17162
17171
  Description?: string;
17163
17172
 
17164
- @Field(() => Int)
17165
- ParentID: number;
17173
+ @Field(() => Int, {nullable: true})
17174
+ ParentID?: number;
17166
17175
 
17167
17176
  @Field()
17168
17177
  @MaxLength(8)
@@ -17172,9 +17181,9 @@ export class ReportCategory_ {
17172
17181
  @MaxLength(8)
17173
17182
  UpdatedAt: Date;
17174
17183
 
17175
- @Field()
17184
+ @Field({nullable: true})
17176
17185
  @MaxLength(200)
17177
- Parent: string;
17186
+ Parent?: string;
17178
17187
 
17179
17188
  @Field(() => [mj_core_schema_server_object_types.ReportCategory_])
17180
17189
  ReportCategoriesArray: mj_core_schema_server_object_types.ReportCategory_[]; // Link to ReportCategories
@@ -17195,7 +17204,7 @@ export class CreateReportCategoryInput {
17195
17204
  @Field({ nullable: true })
17196
17205
  Description: string;
17197
17206
 
17198
- @Field(() => Int)
17207
+ @Field(() => Int, { nullable: true })
17199
17208
  ParentID: number;
17200
17209
  }
17201
17210
 
@@ -17214,7 +17223,7 @@ export class UpdateReportCategoryInput {
17214
17223
  @Field({ nullable: true })
17215
17224
  Description: string;
17216
17225
 
17217
- @Field(() => Int)
17226
+ @Field(() => Int, { nullable: true })
17218
17227
  ParentID: number;
17219
17228
  }
17220
17229
 
@@ -17825,6 +17834,32 @@ export class FileResolver extends ResolverBase {
17825
17834
  const i = input, d = dataSource; // prevent error
17826
17835
  }
17827
17836
 
17837
+ @Mutation(() => File_)
17838
+ async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
17839
+ if (await this.BeforeDelete(dataSource, ID)) { // fire event and proceed if it wasn't cancelled
17840
+ const entityObject = <FileEntity>await new Metadata().GetEntityObject('Files', this.GetUserFromPayload(userPayload));
17841
+ await entityObject.Load(ID);
17842
+ const returnValue = entityObject.GetAll(); // grab the values before we delete so we can return last state before delete if we are successful.
17843
+ if (await entityObject.Delete()) {
17844
+ await this.AfterDelete(dataSource, ID); // fire event
17845
+ return returnValue;
17846
+ }
17847
+ else
17848
+ return null; // delete failed, this will cause an exception
17849
+ }
17850
+ else
17851
+ return null; // BeforeDelete canceled the operation, this will cause an exception
17852
+ }
17853
+
17854
+ // Before/After UPDATE Event Hooks for Sub-Classes to Override
17855
+ protected async BeforeDelete(dataSource: DataSource, ID: number): Promise<boolean> {
17856
+ const i = ID, d = dataSource; // prevent error;
17857
+ return true;
17858
+ }
17859
+ protected async AfterDelete(dataSource: DataSource, ID: number) {
17860
+ const i = ID, d = dataSource; // prevent error
17861
+ }
17862
+
17828
17863
  }
17829
17864
 
17830
17865
  //****************************************************************************
@@ -0,0 +1,104 @@
1
+ import { Metadata } from '@memberjunction/core';
2
+ import { FileEntity, FileStorageProviderEntity } from '@memberjunction/core-entities';
3
+ import {
4
+ AppContext,
5
+ Arg,
6
+ Ctx,
7
+ Field,
8
+ FieldResolver,
9
+ InputType,
10
+ Int,
11
+ Mutation,
12
+ ObjectType,
13
+ PubSub,
14
+ PubSubEngine,
15
+ Resolver,
16
+ Root,
17
+ } from '@memberjunction/server';
18
+ import { createDownloadUrl, createUploadUrl, deleteObject } from '@memberjunction/storage';
19
+ import { CreateFileInput, FileResolver as FileResolverBase, File_ } from '../generated/generated';
20
+
21
+ @InputType()
22
+ export class CreateUploadURLInput {
23
+ @Field(() => Int)
24
+ FileID: number;
25
+ }
26
+
27
+ @ObjectType()
28
+ export class CreateFilePayload {
29
+ @Field(() => File_)
30
+ File: File_;
31
+ @Field(() => String)
32
+ UploadUrl: string;
33
+ }
34
+
35
+ @ObjectType()
36
+ export class FileExt extends File_ {
37
+ @Field(() => String)
38
+ DownloadUrl: string;
39
+ }
40
+
41
+ @Resolver(File_)
42
+ export class FileResolver extends FileResolverBase {
43
+ @Mutation(() => CreateFilePayload)
44
+ async CreateFile(
45
+ @Arg('input', () => CreateFileInput) input: CreateFileInput,
46
+ @Ctx() { dataSource, userPayload }: AppContext,
47
+ @PubSub() pubSub: PubSubEngine
48
+ ) {
49
+ const md = new Metadata();
50
+ const userInfo = this.GetUserFromPayload(userPayload);
51
+ const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', userInfo);
52
+
53
+ const fileRecord = (await super.CreateFile({ ...input, Status: 'Pending' }, { dataSource, userPayload }, pubSub)) as File_;
54
+
55
+ // If there's a problem creating the file record, the base resolver will return null
56
+ if (!fileRecord) {
57
+ return null;
58
+ }
59
+
60
+ // Create the upload URL and get the record updates (provider key, content type, etc)
61
+ const { updatedInput, UploadUrl } = await createUploadUrl(providerEntity, fileRecord);
62
+
63
+ // Save the file record with the updated input
64
+ const fileEntity = <FileEntity>await new Metadata().GetEntityObject('Files', userInfo);
65
+ fileEntity.LoadFromData(input);
66
+ fileEntity.SetMany(updatedInput);
67
+ await fileEntity.Save();
68
+ const File = fileEntity.GetAll();
69
+
70
+ return { File, UploadUrl };
71
+ }
72
+
73
+ @FieldResolver(() => String)
74
+ async DownloadUrl(@Root() file: File_, @Ctx() { userPayload }: AppContext) {
75
+ const md = new Metadata();
76
+ const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>(
77
+ 'File Storage Providers',
78
+ this.GetUserFromPayload(userPayload)
79
+ );
80
+
81
+ const url = await createDownloadUrl(providerEntity, file.ProviderKey ?? file.ID);
82
+
83
+ return url;
84
+ }
85
+
86
+ @Mutation(() => File_)
87
+ async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
88
+ const md = new Metadata();
89
+ const userInfo = this.GetUserFromPayload(userPayload);
90
+
91
+ const entityObject = <FileEntity>await md.GetEntityObject('Files', userInfo);
92
+ await entityObject.Load(ID);
93
+ if (!entityObject) {
94
+ return null;
95
+ }
96
+
97
+ if (entityObject.Status === 'Uploaded') {
98
+ const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', userInfo);
99
+ await deleteObject(providerEntity, entityObject.ProviderKey ?? entityObject.ID);
100
+ }
101
+
102
+ return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
103
+ }
104
+ }