Skip to content

Commit 2967aa2

Browse files
committed
feat: change addTool to multipart data
1 parent 4ce9724 commit 2967aa2

File tree

16 files changed

+244
-17
lines changed

16 files changed

+244
-17
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,5 @@ dist
141141
.pnp.*
142142

143143
*.code-workspace
144+
145+
s3
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- Add column "description" and "cover "to "editor-tools" if it doesn't exist
2+
DO $$
3+
BEGIN
4+
IF NOT EXISTS(SELECT *
5+
FROM information_schema.columns
6+
WHERE table_name='editor_tools' AND column_name='description')
7+
THEN
8+
ALTER TABLE "editor_tools" ADD COLUMN "description" VARCHAR(255); -- Adjust the data type and size as needed
9+
END IF;
10+
IF NOT EXISTS(SELECT *
11+
FROM information_schema.columns
12+
WHERE table_name='editor_tools' AND column_name='cover')
13+
THEN
14+
ALTER TABLE "editor_tools" ADD COLUMN "cover" VARCHAR(255); -- Adjust the data type and size as needed
15+
END IF;
16+
END $$;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"@codex-team/config-loader": "^1.0.0",
4343
"@fastify/cookie": "^8.3.0",
4444
"@fastify/cors": "^8.3.0",
45-
"@fastify/multipart": "^8.2.0",
45+
"@fastify/multipart": "^8.3.0",
4646
"@fastify/oauth2": "^7.2.1",
4747
"@fastify/swagger": "^8.8.0",
4848
"@fastify/swagger-ui": "^1.9.3",

src/domain/entities/editorTools.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ export default interface EditorTool {
2525
*/
2626
exportName: string;
2727

28+
/**
29+
* Description of the tool. It's shown in the marketplace
30+
*/
31+
description?: string;
32+
33+
/**
34+
* S3 key to the tool cover image
35+
*/
36+
cover?: string;
37+
2838
/**
2939
* User id that added the tool to the marketplace
3040
*/

src/domain/entities/file.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ export enum FileType {
1414
/**
1515
* File is a part of note
1616
*/
17-
NoteAttachment = 1
17+
NoteAttachment = 1,
18+
19+
/**
20+
* Tool cover
21+
*/
22+
EditorToolCover = 2
1823
}
1924

2025
/**
@@ -39,17 +44,25 @@ export type NoteAttachmentFileLocation = {
3944
noteId: NoteInternalId;
4045
};
4146

47+
/**
48+
* Editor tool cover location
49+
*/
50+
export type EditorToolCoverFileLocation = {
51+
isEditorToolCover: boolean;
52+
};
53+
4254
/**
4355
* Possible file location
4456
*/
45-
export type FileLocation = TestFileLocation | NoteAttachmentFileLocation;
57+
export type FileLocation = TestFileLocation | NoteAttachmentFileLocation | EditorToolCoverFileLocation;
4658

4759
/**
4860
* File location type, wich depends on file type
4961
*/
5062
export interface FileLocationByType {
5163
[FileType.Test]: TestFileLocation;
5264
[FileType.NoteAttachment]: NoteAttachmentFileLocation;
65+
[FileType.EditorToolCover]: EditorToolCoverFileLocation;
5366
}
5467

5568
/**

src/domain/service/editorTools.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,8 @@ export default class EditorToolsService implements EditorToolsServiceSharedMetho
6363
...editorTool,
6464
});
6565
}
66+
67+
public async updateToolCover(editorToolId: EditorTool['id'], cover: EditorTool['cover']): Promise<void> {
68+
return await this.repository.updateToolCover(editorToolId, cover);
69+
}
6670
}

src/domain/service/fileUploader.service.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { FileData, NoteAttachmentFileLocation, FileLocationByType, FileLocation, FileMetadata } from '@domain/entities/file.js';
1+
import type { FileData, NoteAttachmentFileLocation, FileLocationByType, FileLocation, FileMetadata, EditorToolCoverFileLocation } from '@domain/entities/file.js';
22
import type UploadedFile from '@domain/entities/file.js';
33
import { FileType } from '@domain/entities/file.js';
44
import { createFileId } from '@infrastructure/utils/id.js';
@@ -152,6 +152,10 @@ export default class FileUploaderService {
152152
return FileType.NoteAttachment;
153153
}
154154

155+
if (this.isEditorToolCoverFileLocation(location)) {
156+
return FileType.EditorToolCover;
157+
}
158+
155159
return FileType.Test;
156160
}
157161

@@ -163,6 +167,10 @@ export default class FileUploaderService {
163167
return 'noteId' in location;
164168
}
165169

170+
private isEditorToolCoverFileLocation(location: FileLocation): location is EditorToolCoverFileLocation {
171+
return 'isEditorToolCover' in location;
172+
}
173+
166174
/**
167175
* Define bucket name by file type
168176
* @param fileType - file type
@@ -173,6 +181,8 @@ export default class FileUploaderService {
173181
return 'test';
174182
case FileType.NoteAttachment:
175183
return 'note-attachment';
184+
case FileType.EditorToolCover:
185+
return 'editor-tool-covers';
176186
default:
177187
throw new DomainError('Unknown file type');
178188
}

src/presentation/http/http-api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { DomainError } from '@domain/entities/DomainError.js';
3232
import UploadRouter from './router/upload.js';
3333
import { ajvFilePlugin } from '@fastify/multipart';
3434
import { UploadSchema } from './schema/Upload.js';
35+
import { AddEditorToolSchema } from './schema/AddEditorTool.js';
3536

3637
const appServerLogger = getLogger('appServer');
3738

@@ -245,6 +246,8 @@ export default class HttpApi implements Api {
245246
await this.server?.register(EditorToolsRouter, {
246247
prefix: '/editor-tools',
247248
editorToolsService: domainServices.editorToolsService,
249+
fileUploaderService: domainServices.fileUploaderService,
250+
fileSizeLimit: this.config.fileSizeLimit,
248251
});
249252

250253
await this.server?.register(UploadRouter, {
@@ -292,6 +295,7 @@ export default class HttpApi implements Api {
292295
this.server?.addSchema(UserSchema);
293296
this.server?.addSchema(NoteSchema);
294297
this.server?.addSchema(EditorToolSchema);
298+
this.server?.addSchema(AddEditorToolSchema);
295299
this.server?.addSchema(NoteSettingsSchema);
296300
this.server?.addSchema(JoinSchemaParams);
297301
this.server?.addSchema(JoinSchemaResponse);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import EditorTool from '@domain/entities/editorTools.js';
2+
import type { MultipartFields, MultipartFile, MultipartValue } from '@fastify/multipart';
3+
import { Multipart } from '@fastify/multipart';
4+
5+
export interface AddEditorToolDto extends MultipartFields {
6+
name: MultipartValue;
7+
title: MultipartValue;
8+
exportName: MultipartValue;
9+
description: MultipartValue;
10+
isDefault?: MultipartValue;
11+
userId: MultipartValue;
12+
source: MultipartValue;
13+
cover: MultipartFile;
14+
}

src/presentation/http/router/editorTools.ts

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { FastifyPluginCallback } from 'fastify';
22
import type EditorToolsService from '@domain/service/editorTools.js';
33
import type EditorTool from '@domain/entities/editorTools.js';
4+
import type { AddEditorToolDto } from './dto/AddEditorTool.dto.js';
5+
import type FileUploaderService from '@domain/service/fileUploader.service.js';
6+
import fastifyMultipart from '@fastify/multipart';
7+
import { createFileId } from '@infrastructure/utils/id.js';
48

59
/**
610
* Interface for the editor tools router
@@ -10,6 +14,16 @@ interface EditorToolsRouterOptions {
1014
* Editor tools service instance
1115
*/
1216
editorToolsService: EditorToolsService;
17+
18+
/**
19+
* File uploader service instance, needed to upload tool cover
20+
*/
21+
fileUploaderService: FileUploaderService;
22+
23+
/**
24+
* Limit for uploaded files size
25+
*/
26+
fileSizeLimit: number;
1327
}
1428

1529
/**
@@ -18,11 +32,18 @@ interface EditorToolsRouterOptions {
1832
* @param opts - empty options
1933
* @param done - callback
2034
*/
21-
const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fastify, opts, done) => {
35+
const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = async (fastify, opts, done) => {
2236
/**
2337
* Manage editor tools data
2438
*/
25-
const { editorToolsService } = opts;
39+
const { editorToolsService, fileUploaderService } = opts;
40+
41+
await fastify.register(fastifyMultipart, {
42+
limits: {
43+
fieldSize: opts.fileSizeLimit,
44+
},
45+
attachFieldsToBody: true,
46+
});
2647

2748
/**
2849
* Get all avaiable editor tools
@@ -59,7 +80,7 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
5980
* Add editor tool to the library of all tools
6081
*/
6182
fastify.post<{
62-
Body: EditorTool;
83+
Body: AddEditorToolDto;
6384
}>('/add-tool', {
6485
config: {
6586
/**
@@ -70,9 +91,10 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
7091
],
7192
},
7293
schema: {
73-
body: {
74-
$ref: 'EditorToolSchema',
75-
},
94+
consumes: ['multipart/form-data'],
95+
// body: {
96+
// $ref: 'AddEditorToolSchema',
97+
// },
7698
response: {
7799
'2xx': {
78100
description: 'Editor tool fields',
@@ -92,7 +114,31 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
92114
const editorTool = request.body;
93115
const userId = request.userId as number;
94116

95-
const tool = await editorToolsService.addTool(editorTool, userId);
117+
let coverKey: string | undefined = undefined;
118+
119+
if (editorTool.cover) {
120+
const coverBuffer = await editorTool.cover.toBuffer();
121+
122+
coverKey = await fileUploaderService.uploadFile({
123+
data: coverBuffer,
124+
name: createFileId(),
125+
mimetype: editorTool.cover.mimetype,
126+
}, {
127+
isEditorToolCover: true,
128+
}, {
129+
userId,
130+
});
131+
}
132+
133+
const tool = await editorToolsService.addTool({
134+
title: String(editorTool.title?.value),
135+
name: String(editorTool.name?.value),
136+
exportName: String(editorTool.exportName?.value),
137+
description: String(editorTool.description?.value),
138+
source: JSON.parse(String(editorTool.source?.value)),
139+
isDefault: Boolean(editorTool.isDefault?.value ?? false),
140+
cover: coverKey ?? '',
141+
}, userId);
96142

97143
return reply.send({
98144
data: tool,

0 commit comments

Comments
 (0)