Skip to content

Commit

Permalink
feat: change addTool to multipart data
Browse files Browse the repository at this point in the history
  • Loading branch information
GeekaN2 committed Jul 2, 2024
1 parent 4ce9724 commit 2967aa2
Show file tree
Hide file tree
Showing 16 changed files with 244 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,5 @@ dist
.pnp.*

*.code-workspace

s3
16 changes: 16 additions & 0 deletions migrations/tenant/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- Add column "description" and "cover "to "editor-tools" if it doesn't exist
DO $$
BEGIN
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' AND column_name='description')
THEN
ALTER TABLE "editor_tools" ADD COLUMN "description" VARCHAR(255); -- Adjust the data type and size as needed
END IF;
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' AND column_name='cover')
THEN
ALTER TABLE "editor_tools" ADD COLUMN "cover" VARCHAR(255); -- Adjust the data type and size as needed
END IF;
END $$;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@codex-team/config-loader": "^1.0.0",
"@fastify/cookie": "^8.3.0",
"@fastify/cors": "^8.3.0",
"@fastify/multipart": "^8.2.0",
"@fastify/multipart": "^8.3.0",
"@fastify/oauth2": "^7.2.1",
"@fastify/swagger": "^8.8.0",
"@fastify/swagger-ui": "^1.9.3",
Expand Down
10 changes: 10 additions & 0 deletions src/domain/entities/editorTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ export default interface EditorTool {
*/
exportName: string;

/**
* Description of the tool. It's shown in the marketplace
*/
description?: string;

/**
* S3 key to the tool cover image
*/
cover?: string;

/**
* User id that added the tool to the marketplace
*/
Expand Down
17 changes: 15 additions & 2 deletions src/domain/entities/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ export enum FileType {
/**
* File is a part of note
*/
NoteAttachment = 1
NoteAttachment = 1,

/**
* Tool cover
*/
EditorToolCover = 2
}

/**
Expand All @@ -39,17 +44,25 @@ export type NoteAttachmentFileLocation = {
noteId: NoteInternalId;
};

/**
* Editor tool cover location
*/
export type EditorToolCoverFileLocation = {
isEditorToolCover: boolean;
};

/**
* Possible file location
*/
export type FileLocation = TestFileLocation | NoteAttachmentFileLocation;
export type FileLocation = TestFileLocation | NoteAttachmentFileLocation | EditorToolCoverFileLocation;

/**
* File location type, wich depends on file type
*/
export interface FileLocationByType {
[FileType.Test]: TestFileLocation;
[FileType.NoteAttachment]: NoteAttachmentFileLocation;
[FileType.EditorToolCover]: EditorToolCoverFileLocation;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/domain/service/editorTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,8 @@ export default class EditorToolsService implements EditorToolsServiceSharedMetho
...editorTool,
});
}

public async updateToolCover(editorToolId: EditorTool['id'], cover: EditorTool['cover']): Promise<void> {
return await this.repository.updateToolCover(editorToolId, cover);
}
}
12 changes: 11 additions & 1 deletion src/domain/service/fileUploader.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FileData, NoteAttachmentFileLocation, FileLocationByType, FileLocation, FileMetadata } from '@domain/entities/file.js';
import type { FileData, NoteAttachmentFileLocation, FileLocationByType, FileLocation, FileMetadata, EditorToolCoverFileLocation } from '@domain/entities/file.js';
import type UploadedFile from '@domain/entities/file.js';
import { FileType } from '@domain/entities/file.js';
import { createFileId } from '@infrastructure/utils/id.js';
Expand Down Expand Up @@ -152,6 +152,10 @@ export default class FileUploaderService {
return FileType.NoteAttachment;
}

if (this.isEditorToolCoverFileLocation(location)) {
return FileType.EditorToolCover;
}

return FileType.Test;
}

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

private isEditorToolCoverFileLocation(location: FileLocation): location is EditorToolCoverFileLocation {
return 'isEditorToolCover' in location;
}

/**
* Define bucket name by file type
* @param fileType - file type
Expand All @@ -173,6 +181,8 @@ export default class FileUploaderService {
return 'test';
case FileType.NoteAttachment:
return 'note-attachment';
case FileType.EditorToolCover:
return 'editor-tool-covers';
default:
throw new DomainError('Unknown file type');
}
Expand Down
4 changes: 4 additions & 0 deletions src/presentation/http/http-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { DomainError } from '@domain/entities/DomainError.js';
import UploadRouter from './router/upload.js';
import { ajvFilePlugin } from '@fastify/multipart';
import { UploadSchema } from './schema/Upload.js';
import { AddEditorToolSchema } from './schema/AddEditorTool.js';

const appServerLogger = getLogger('appServer');

Expand Down Expand Up @@ -245,6 +246,8 @@ export default class HttpApi implements Api {
await this.server?.register(EditorToolsRouter, {
prefix: '/editor-tools',
editorToolsService: domainServices.editorToolsService,
fileUploaderService: domainServices.fileUploaderService,
fileSizeLimit: this.config.fileSizeLimit,
});

await this.server?.register(UploadRouter, {
Expand Down Expand Up @@ -292,6 +295,7 @@ export default class HttpApi implements Api {
this.server?.addSchema(UserSchema);
this.server?.addSchema(NoteSchema);
this.server?.addSchema(EditorToolSchema);
this.server?.addSchema(AddEditorToolSchema);
this.server?.addSchema(NoteSettingsSchema);
this.server?.addSchema(JoinSchemaParams);
this.server?.addSchema(JoinSchemaResponse);
Expand Down
14 changes: 14 additions & 0 deletions src/presentation/http/router/dto/AddEditorTool.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import EditorTool from '@domain/entities/editorTools.js';
import type { MultipartFields, MultipartFile, MultipartValue } from '@fastify/multipart';
import { Multipart } from '@fastify/multipart';

export interface AddEditorToolDto extends MultipartFields {
name: MultipartValue;
title: MultipartValue;
exportName: MultipartValue;
description: MultipartValue;
isDefault?: MultipartValue;
userId: MultipartValue;
source: MultipartValue;
cover: MultipartFile;
}
60 changes: 53 additions & 7 deletions src/presentation/http/router/editorTools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { FastifyPluginCallback } from 'fastify';
import type EditorToolsService from '@domain/service/editorTools.js';
import type EditorTool from '@domain/entities/editorTools.js';
import type { AddEditorToolDto } from './dto/AddEditorTool.dto.js';
import type FileUploaderService from '@domain/service/fileUploader.service.js';
import fastifyMultipart from '@fastify/multipart';
import { createFileId } from '@infrastructure/utils/id.js';

/**
* Interface for the editor tools router
Expand All @@ -10,6 +14,16 @@ interface EditorToolsRouterOptions {
* Editor tools service instance
*/
editorToolsService: EditorToolsService;

/**
* File uploader service instance, needed to upload tool cover
*/
fileUploaderService: FileUploaderService;

/**
* Limit for uploaded files size
*/
fileSizeLimit: number;
}

/**
Expand All @@ -18,11 +32,18 @@ interface EditorToolsRouterOptions {
* @param opts - empty options
* @param done - callback
*/
const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fastify, opts, done) => {
const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = async (fastify, opts, done) => {
/**
* Manage editor tools data
*/
const { editorToolsService } = opts;
const { editorToolsService, fileUploaderService } = opts;

await fastify.register(fastifyMultipart, {
limits: {
fieldSize: opts.fileSizeLimit,
},
attachFieldsToBody: true,
});

/**
* Get all avaiable editor tools
Expand Down Expand Up @@ -59,7 +80,7 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
* Add editor tool to the library of all tools
*/
fastify.post<{
Body: EditorTool;
Body: AddEditorToolDto;
}>('/add-tool', {
config: {
/**
Expand All @@ -70,9 +91,10 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
],
},
schema: {
body: {
$ref: 'EditorToolSchema',
},
consumes: ['multipart/form-data'],
// body: {
// $ref: 'AddEditorToolSchema',
// },
response: {
'2xx': {
description: 'Editor tool fields',
Expand All @@ -92,7 +114,31 @@ const EditorToolsRouter: FastifyPluginCallback<EditorToolsRouterOptions> = (fast
const editorTool = request.body;
const userId = request.userId as number;

const tool = await editorToolsService.addTool(editorTool, userId);
let coverKey: string | undefined = undefined;

if (editorTool.cover) {
const coverBuffer = await editorTool.cover.toBuffer();

coverKey = await fileUploaderService.uploadFile({
data: coverBuffer,
name: createFileId(),
mimetype: editorTool.cover.mimetype,
}, {
isEditorToolCover: true,
}, {
userId,
});
}

const tool = await editorToolsService.addTool({
title: String(editorTool.title?.value),
name: String(editorTool.name?.value),
exportName: String(editorTool.exportName?.value),
description: String(editorTool.description?.value),
source: JSON.parse(String(editorTool.source?.value)),
isDefault: Boolean(editorTool.isDefault?.value ?? false),
cover: coverKey ?? '',
}, userId);

return reply.send({
data: tool,
Expand Down
1 change: 0 additions & 1 deletion src/presentation/http/router/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const OauthRouter: FastifyPluginCallback<OauthRouterOptions> = (fastify, opts, d
* Get referer from request headers
*/
const { token } = await fastify.googleOAuth2.getAccessTokenFromAuthorizationCodeFlow(request);

const user = await opts.userService.getUserByProvider(token.access_token, Provider.GOOGLE);

/**
Expand Down
55 changes: 55 additions & 0 deletions src/presentation/http/schema/AddEditorTool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export const AddEditorToolSchema = {
$id: 'AddEditorToolSchema',
type: 'object',
required: [
'name',
'title',
'exportName',
'source',
],
properties: {
id: {
type: 'string',
readOnly: true,
description: 'Unique tool id',
},
name: {
type: 'string',
description: 'Plugin id that editor will use, e.g. "warning", "list", "linkTool"',
},
title: {
type: 'string',
description: 'User-friendly name that will be shown in marketplace, .e.g "Warning tool 3000"',
},
exportName: {
type: 'string',
description: 'Name of the plugin\'s class, e.g. "LinkTool", "Checklist", "Header"',
},
description: {
type: 'string',
description: 'Plugin description that will be shown in the marketplace',
},
cover: {
type: 'string',
description: 'Multipart data',
},
isDefault: {
type: 'boolean',
description: 'Is plugin included by default in the editor',
default: false,
},
userId: {
type: ['number', 'null'],
description: 'User id that added the tool to the marketplace',
},
source: {
type: 'object',
properties: {
cdn: {
type: 'string',
description: 'Tool URL in content delivery network',
},
},
},
},
};
8 changes: 8 additions & 0 deletions src/presentation/http/schema/EditorTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ export const EditorToolSchema = {
type: 'string',
description: 'Name of the plugin\'s class, e.g. "LinkTool", "Checklist", "Header"',
},
description: {
type: 'string',
description: 'Plugin description that will be shown in the marketplace',
},
cover: {
type: 'string',
description: 'S3 key to the tool cover image',
},
isDefault: {
type: 'boolean',
description: 'Is plugin included by default in the editor',
Expand Down
9 changes: 9 additions & 0 deletions src/repository/editorTools.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,13 @@ export default class EditorToolsRepository {

return editorTools;
}

/**
* Update tool cover
* @param editorToolId
* @param cover
*/
public async updateToolCover(editorToolId: EditorTool['id'], cover: EditorTool['cover']): Promise<void> {
return await this.storage.updateToolCover(editorToolId, cover);
}
}
Loading

0 comments on commit 2967aa2

Please sign in to comment.