Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: change addTool to multipart data
  • Loading branch information
GeekaN2 committed Jul 4, 2024
commit 6e5f088131aea7b2703f18915aa0c92beff45b82
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,5 @@ dist
.pnp.*

*.code-workspace

s3
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 @@ -43,7 +43,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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the numbers mean? Add description please

Comment on lines +17 to +22
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets store this as string enum for better readability

}

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

/**
* Editor tool cover location
*/
export type EditorToolCoverFileLocation = {
isEditorToolCover: boolean;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe store toolId?

};

/**
* 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> {
Comment thread
neSpecc marked this conversation as resolved.
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 @@ -181,6 +181,10 @@ export default class FileUploaderService {
return FileType.NoteAttachment;
}

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

return FileType.Test;
}

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

private isEditorToolCoverFileLocation(location: FileLocation): location is EditorToolCoverFileLocation {
Comment thread
neSpecc marked this conversation as resolved.
return 'isEditorToolCover' in location;
}

/**
* Define bucket name by file type
* @param fileType - file type
Expand All @@ -202,6 +210,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 {
Comment thread
neSpecc marked this conversation as resolved.
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, {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the fastify.registed should be stored here
notes.api/src/presentation/http/http-api.ts

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',
// },
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it, maybe add real validation?

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,
});
}
Comment on lines +118 to +130
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets move this logic into addTool()


const tool = await editorToolsService.addTool({
title: String(editorTool.title?.value),
name: String(editorTool.name?.value),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsafe call

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> {
Comment on lines +61 to +66
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty docs

return await this.storage.updateToolCover(editorToolId, cover);
}
}
Loading