@memberjunction/server 1.0.6 → 1.0.7
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.
- package/.eslintignore +4 -4
- package/.eslintrc +24 -24
- package/CHANGELOG.json +92 -0
- package/CHANGELOG.md +25 -0
- package/README.md +141 -141
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts +23 -0
- package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -0
- package/dist/entitySubclasses/entityPermissions.server.js +99 -0
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -0
- package/dist/entitySubclasses/userViewEntity.server.js +17 -17
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.js +10 -10
- package/dist/resolvers/FileCategoryResolver.js +2 -2
- package/dist/resolvers/ReportResolver.js +4 -4
- package/package.json +80 -80
- package/src/apolloServer/TransactionPlugin.ts +57 -57
- package/src/apolloServer/index.ts +33 -33
- package/src/auth/exampleNewUserSubClass.ts +73 -73
- package/src/auth/index.ts +151 -151
- package/src/auth/newUsers.ts +56 -56
- package/src/auth/tokenExpiredError.ts +12 -12
- package/src/cache.ts +10 -10
- package/src/config.ts +89 -84
- package/src/context.ts +119 -119
- package/src/directives/Public.ts +42 -42
- package/src/directives/index.ts +1 -1
- package/src/entitySubclasses/entityPermissions.server.ts +111 -0
- package/src/entitySubclasses/userViewEntity.server.ts +187 -187
- package/src/generated/generated.ts +2573 -2573
- package/src/generic/PushStatusResolver.ts +40 -40
- package/src/generic/ResolverBase.ts +331 -331
- package/src/generic/RunViewResolver.ts +350 -350
- package/src/index.ts +133 -137
- package/src/orm.ts +36 -36
- package/src/resolvers/AskSkipResolver.ts +782 -782
- package/src/resolvers/ColorResolver.ts +72 -72
- package/src/resolvers/DatasetResolver.ts +115 -115
- package/src/resolvers/EntityRecordNameResolver.ts +77 -77
- package/src/resolvers/EntityResolver.ts +37 -37
- package/src/resolvers/FileCategoryResolver.ts +38 -38
- package/src/resolvers/FileResolver.ts +110 -110
- package/src/resolvers/MergeRecordsResolver.ts +198 -198
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +59 -59
- package/src/resolvers/QueryResolver.ts +42 -42
- package/src/resolvers/ReportResolver.ts +131 -131
- package/src/resolvers/UserFavoriteResolver.ts +102 -102
- package/src/resolvers/UserResolver.ts +29 -29
- package/src/resolvers/UserViewResolver.ts +64 -64
- package/src/types.ts +19 -19
- package/src/util.ts +106 -106
- package/tsconfig.json +31 -31
- package/typedoc.json +4 -4
- package/build.log.json +0 -47
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { EntityPermissionType, Metadata } from '@memberjunction/core';
|
|
2
|
-
import { FileCategoryEntity, FileEntity } from '@memberjunction/core-entities';
|
|
3
|
-
import { AppContext, Arg, Ctx, Int, Mutation } from '@memberjunction/server';
|
|
4
|
-
import { mj_core_schema } from '../config';
|
|
5
|
-
import { FileCategoryResolver as FileCategoryResolverBase, FileCategory_ } from '../generated/generated';
|
|
6
|
-
|
|
7
|
-
export class FileResolver extends FileCategoryResolverBase {
|
|
8
|
-
@Mutation(() => FileCategory_)
|
|
9
|
-
async DeleteFileCategory(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext) {
|
|
10
|
-
if (!(await this.BeforeDelete(dataSource, ID))) {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const md = await new Metadata();
|
|
15
|
-
const user = this.GetUserFromPayload(userPayload);
|
|
16
|
-
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
17
|
-
const fileCategoryEntity = await md.GetEntityObject<FileCategoryEntity>('File Categories', user);
|
|
18
|
-
|
|
19
|
-
fileEntity.CheckPermissions(EntityPermissionType.Update, true);
|
|
20
|
-
fileCategoryEntity.CheckPermissions(EntityPermissionType.Delete, true);
|
|
21
|
-
|
|
22
|
-
await fileCategoryEntity.Load(ID);
|
|
23
|
-
const returnValue = fileCategoryEntity.GetAll();
|
|
24
|
-
|
|
25
|
-
// Any files using the deleted category fall back to its parent
|
|
26
|
-
await dataSource.transaction(async () => {
|
|
27
|
-
const sSQL = `UPDATE [${mj_core_schema}].[File]
|
|
28
|
-
SET [CategoryID]=${fileCategoryEntity.ParentID}
|
|
29
|
-
WHERE [CategoryID]=${fileCategoryEntity.ID}`;
|
|
30
|
-
|
|
31
|
-
await dataSource.query(sSQL);
|
|
32
|
-
await fileCategoryEntity.Delete();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
await this.AfterDelete(dataSource, ID); // fire event
|
|
36
|
-
return returnValue;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
1
|
+
import { EntityPermissionType, Metadata } from '@memberjunction/core';
|
|
2
|
+
import { FileCategoryEntity, FileEntity } from '@memberjunction/core-entities';
|
|
3
|
+
import { AppContext, Arg, Ctx, Int, Mutation } from '@memberjunction/server';
|
|
4
|
+
import { mj_core_schema } from '../config';
|
|
5
|
+
import { FileCategoryResolver as FileCategoryResolverBase, FileCategory_ } from '../generated/generated';
|
|
6
|
+
|
|
7
|
+
export class FileResolver extends FileCategoryResolverBase {
|
|
8
|
+
@Mutation(() => FileCategory_)
|
|
9
|
+
async DeleteFileCategory(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext) {
|
|
10
|
+
if (!(await this.BeforeDelete(dataSource, ID))) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const md = await new Metadata();
|
|
15
|
+
const user = this.GetUserFromPayload(userPayload);
|
|
16
|
+
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
17
|
+
const fileCategoryEntity = await md.GetEntityObject<FileCategoryEntity>('File Categories', user);
|
|
18
|
+
|
|
19
|
+
fileEntity.CheckPermissions(EntityPermissionType.Update, true);
|
|
20
|
+
fileCategoryEntity.CheckPermissions(EntityPermissionType.Delete, true);
|
|
21
|
+
|
|
22
|
+
await fileCategoryEntity.Load(ID);
|
|
23
|
+
const returnValue = fileCategoryEntity.GetAll();
|
|
24
|
+
|
|
25
|
+
// Any files using the deleted category fall back to its parent
|
|
26
|
+
await dataSource.transaction(async () => {
|
|
27
|
+
const sSQL = `UPDATE [${mj_core_schema}].[File]
|
|
28
|
+
SET [CategoryID]=${fileCategoryEntity.ParentID}
|
|
29
|
+
WHERE [CategoryID]=${fileCategoryEntity.ID}`;
|
|
30
|
+
|
|
31
|
+
await dataSource.query(sSQL);
|
|
32
|
+
await fileCategoryEntity.Delete();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await this.AfterDelete(dataSource, ID); // fire event
|
|
36
|
+
return returnValue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
import { EntityPermissionType, 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 user = this.GetUserFromPayload(userPayload);
|
|
51
|
-
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
52
|
-
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
53
|
-
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
54
|
-
|
|
55
|
-
const fileRecord = (await super.CreateFile({ ...input, Status: 'Pending' }, { dataSource, userPayload }, pubSub)) as File_;
|
|
56
|
-
|
|
57
|
-
// If there's a problem creating the file record, the base resolver will return null
|
|
58
|
-
if (!fileRecord) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Create the upload URL and get the record updates (provider key, content type, etc)
|
|
63
|
-
const { updatedInput, UploadUrl } = await createUploadUrl(providerEntity, fileRecord);
|
|
64
|
-
|
|
65
|
-
// Save the file record with the updated input
|
|
66
|
-
fileEntity.LoadFromData(input);
|
|
67
|
-
fileEntity.SetMany(updatedInput);
|
|
68
|
-
await fileEntity.Save();
|
|
69
|
-
const File = fileEntity.GetAll();
|
|
70
|
-
|
|
71
|
-
return { File, UploadUrl };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@FieldResolver(() => String)
|
|
75
|
-
async DownloadUrl(@Root() file: File_, @Ctx() { userPayload }: AppContext) {
|
|
76
|
-
const md = new Metadata();
|
|
77
|
-
const user = this.GetUserFromPayload(userPayload);
|
|
78
|
-
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
79
|
-
fileEntity.CheckPermissions(EntityPermissionType.Read, true);
|
|
80
|
-
|
|
81
|
-
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
82
|
-
await providerEntity.Load(file.ProviderID);
|
|
83
|
-
|
|
84
|
-
const url = await createDownloadUrl(providerEntity, file.ProviderKey ?? file.ID);
|
|
85
|
-
|
|
86
|
-
return url;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@Mutation(() => File_)
|
|
90
|
-
async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
91
|
-
const md = new Metadata();
|
|
92
|
-
const userInfo = this.GetUserFromPayload(userPayload);
|
|
93
|
-
|
|
94
|
-
const fileEntity = await md.GetEntityObject<FileEntity>('Files', userInfo);
|
|
95
|
-
await fileEntity.Load(ID);
|
|
96
|
-
if (!fileEntity) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
fileEntity.CheckPermissions(EntityPermissionType.Delete, true);
|
|
100
|
-
|
|
101
|
-
// Only delete the object from the provider if it's actually been uploaded
|
|
102
|
-
if (fileEntity.Status === 'Uploaded') {
|
|
103
|
-
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', userInfo);
|
|
104
|
-
await providerEntity.Load(fileEntity.ProviderID);
|
|
105
|
-
await deleteObject(providerEntity, fileEntity.ProviderKey ?? fileEntity.ID);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
1
|
+
import { EntityPermissionType, 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 user = this.GetUserFromPayload(userPayload);
|
|
51
|
+
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
52
|
+
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
53
|
+
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
54
|
+
|
|
55
|
+
const fileRecord = (await super.CreateFile({ ...input, Status: 'Pending' }, { dataSource, userPayload }, pubSub)) as File_;
|
|
56
|
+
|
|
57
|
+
// If there's a problem creating the file record, the base resolver will return null
|
|
58
|
+
if (!fileRecord) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Create the upload URL and get the record updates (provider key, content type, etc)
|
|
63
|
+
const { updatedInput, UploadUrl } = await createUploadUrl(providerEntity, fileRecord);
|
|
64
|
+
|
|
65
|
+
// Save the file record with the updated input
|
|
66
|
+
fileEntity.LoadFromData(input);
|
|
67
|
+
fileEntity.SetMany(updatedInput);
|
|
68
|
+
await fileEntity.Save();
|
|
69
|
+
const File = fileEntity.GetAll();
|
|
70
|
+
|
|
71
|
+
return { File, UploadUrl };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@FieldResolver(() => String)
|
|
75
|
+
async DownloadUrl(@Root() file: File_, @Ctx() { userPayload }: AppContext) {
|
|
76
|
+
const md = new Metadata();
|
|
77
|
+
const user = this.GetUserFromPayload(userPayload);
|
|
78
|
+
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
79
|
+
fileEntity.CheckPermissions(EntityPermissionType.Read, true);
|
|
80
|
+
|
|
81
|
+
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', user);
|
|
82
|
+
await providerEntity.Load(file.ProviderID);
|
|
83
|
+
|
|
84
|
+
const url = await createDownloadUrl(providerEntity, file.ProviderKey ?? file.ID);
|
|
85
|
+
|
|
86
|
+
return url;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@Mutation(() => File_)
|
|
90
|
+
async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
91
|
+
const md = new Metadata();
|
|
92
|
+
const userInfo = this.GetUserFromPayload(userPayload);
|
|
93
|
+
|
|
94
|
+
const fileEntity = await md.GetEntityObject<FileEntity>('Files', userInfo);
|
|
95
|
+
await fileEntity.Load(ID);
|
|
96
|
+
if (!fileEntity) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
fileEntity.CheckPermissions(EntityPermissionType.Delete, true);
|
|
100
|
+
|
|
101
|
+
// Only delete the object from the provider if it's actually been uploaded
|
|
102
|
+
if (fileEntity.Status === 'Uploaded') {
|
|
103
|
+
const providerEntity = await md.GetEntityObject<FileStorageProviderEntity>('File Storage Providers', userInfo);
|
|
104
|
+
await providerEntity.Load(fileEntity.ProviderID);
|
|
105
|
+
await deleteObject(providerEntity, fileEntity.ProviderKey ?? fileEntity.ID);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
|
|
109
|
+
}
|
|
110
|
+
}
|