wip
This commit is contained in:
		| @@ -5,45 +5,10 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | |||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
| export const meta = { |  | ||||||
| 	tags: ['drive', 'notes'], |  | ||||||
|  |  | ||||||
| 	requireCredential: true, |  | ||||||
|  |  | ||||||
| 	kind: 'read:drive', |  | ||||||
|  |  | ||||||
| 	description: 'Find the notes to which the given file is attached.', |  | ||||||
|  |  | ||||||
| 	res: { |  | ||||||
| 		type: 'array', |  | ||||||
| 		optional: false, nullable: false, |  | ||||||
| 		items: { |  | ||||||
| 			type: 'object', |  | ||||||
| 			optional: false, nullable: false, |  | ||||||
| 			ref: 'Note', |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	errors: { |  | ||||||
| 		noSuchFile: { |  | ||||||
| 			message: 'No such file.', |  | ||||||
| 			code: 'NO_SUCH_FILE', |  | ||||||
| 			id: 'c118ece3-2e4b-4296-99d1-51756e32d232', |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| export const paramDef = { |  | ||||||
| 	type: 'object', |  | ||||||
| 	properties: { |  | ||||||
| 		fileId: { type: 'string', format: 'misskey:id' }, |  | ||||||
| 	}, |  | ||||||
| 	required: ['fileId'], |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| // eslint-disable-next-line import/no-default-export | // eslint-disable-next-line import/no-default-export | ||||||
| @Injectable() | @Injectable() | ||||||
| export default class extends Endpoint<typeof meta, typeof paramDef> { | export default class extends Endpoint<'drive/files/attached-notes'> { | ||||||
|  | 	name = 'drive/files/attached-notes' as const; | ||||||
| 	constructor( | 	constructor( | ||||||
| 		@Inject(DI.driveFilesRepository) | 		@Inject(DI.driveFilesRepository) | ||||||
| 		private driveFilesRepository: DriveFilesRepository, | 		private driveFilesRepository: DriveFilesRepository, | ||||||
| @@ -53,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||||||
|  |  | ||||||
| 		private noteEntityService: NoteEntityService, | 		private noteEntityService: NoteEntityService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(async (ps, me) => { | ||||||
| 			// Fetch file | 			// Fetch file | ||||||
| 			const file = await this.driveFilesRepository.findOneBy({ | 			const file = await this.driveFilesRepository.findOneBy({ | ||||||
| 				id: ps.fileId, | 				id: ps.fileId, | ||||||
| @@ -61,7 +26,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			if (file == null) { | 			if (file == null) { | ||||||
| 				throw new ApiError(meta.errors.noSuchFile); | 				throw new ApiError(this.meta.errors.noSuchFile); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			const notes = await this.notesRepository.createQueryBuilder('note') | 			const notes = await this.notesRepository.createQueryBuilder('note') | ||||||
|   | |||||||
| @@ -3,37 +3,15 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | |||||||
| import type { DriveFilesRepository } from '@/models/index.js'; | import type { DriveFilesRepository } from '@/models/index.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  |  | ||||||
| export const meta = { |  | ||||||
| 	tags: ['drive'], |  | ||||||
|  |  | ||||||
| 	requireCredential: true, |  | ||||||
|  |  | ||||||
| 	kind: 'read:drive', |  | ||||||
|  |  | ||||||
| 	description: 'Check if a given file exists.', |  | ||||||
|  |  | ||||||
| 	res: { |  | ||||||
| 		type: 'boolean', |  | ||||||
| 		optional: false, nullable: false, |  | ||||||
| 	}, |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| export const paramDef = { |  | ||||||
| 	type: 'object', |  | ||||||
| 	properties: { |  | ||||||
| 		md5: { type: 'string' }, |  | ||||||
| 	}, |  | ||||||
| 	required: ['md5'], |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| // eslint-disable-next-line import/no-default-export | // eslint-disable-next-line import/no-default-export | ||||||
| @Injectable() | @Injectable() | ||||||
| export default class extends Endpoint<typeof meta, typeof paramDef> { | export default class extends Endpoint<'drive/files/check-existence'> { | ||||||
|  | 	name = 'drive/files/check-existence' as const; | ||||||
| 	constructor( | 	constructor( | ||||||
| 		@Inject(DI.driveFilesRepository) | 		@Inject(DI.driveFilesRepository) | ||||||
| 		private driveFilesRepository: DriveFilesRepository, | 		private driveFilesRepository: DriveFilesRepository, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(async (ps, me) => { | ||||||
| 			const file = await this.driveFilesRepository.findOneBy({ | 			const file = await this.driveFilesRepository.findOneBy({ | ||||||
| 				md5: ps.md5, | 				md5: ps.md5, | ||||||
| 				userId: me.id, | 				userId: me.id, | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| import ms from 'ms'; |  | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { DriveFilesRepository } from '@/models/index.js'; | import type { DriveFilesRepository } from '@/models/index.js'; | ||||||
| import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js'; | import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js'; | ||||||
| @@ -10,66 +9,10 @@ import { DriveService } from '@/core/DriveService.js'; | |||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
| export const meta = { |  | ||||||
| 	tags: ['drive'], |  | ||||||
|  |  | ||||||
| 	requireCredential: true, |  | ||||||
|  |  | ||||||
| 	prohibitMoved: true, |  | ||||||
|  |  | ||||||
| 	limit: { |  | ||||||
| 		duration: ms('1hour'), |  | ||||||
| 		max: 120, |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	requireFile: true, |  | ||||||
|  |  | ||||||
| 	kind: 'write:drive', |  | ||||||
|  |  | ||||||
| 	description: 'Upload a new drive file.', |  | ||||||
|  |  | ||||||
| 	res: { |  | ||||||
| 		type: 'object', |  | ||||||
| 		optional: false, nullable: false, |  | ||||||
| 		ref: 'DriveFile', |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	errors: { |  | ||||||
| 		invalidFileName: { |  | ||||||
| 			message: 'Invalid file name.', |  | ||||||
| 			code: 'INVALID_FILE_NAME', |  | ||||||
| 			id: 'f449b209-0c60-4e51-84d5-29486263bfd4', |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		inappropriate: { |  | ||||||
| 			message: 'Cannot upload the file because it has been determined that it possibly contains inappropriate content.', |  | ||||||
| 			code: 'INAPPROPRIATE', |  | ||||||
| 			id: 'bec5bd69-fba3-43c9-b4fb-2894b66ad5d2', |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		noFreeSpace: { |  | ||||||
| 			message: 'Cannot upload the file because you have no free space of drive.', |  | ||||||
| 			code: 'NO_FREE_SPACE', |  | ||||||
| 			id: 'd08dbc37-a6a9-463a-8c47-96c32ab5f064', |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| export const paramDef = { |  | ||||||
| 	type: 'object', |  | ||||||
| 	properties: { |  | ||||||
| 		folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, |  | ||||||
| 		name: { type: 'string', nullable: true, default: null }, |  | ||||||
| 		comment: { type: 'string', nullable: true, maxLength: DB_MAX_IMAGE_COMMENT_LENGTH, default: null }, |  | ||||||
| 		isSensitive: { type: 'boolean', default: false }, |  | ||||||
| 		force: { type: 'boolean', default: false }, |  | ||||||
| 	}, |  | ||||||
| 	required: [], |  | ||||||
| } as const; |  | ||||||
|  |  | ||||||
| // eslint-disable-next-line import/no-default-export | // eslint-disable-next-line import/no-default-export | ||||||
| @Injectable() | @Injectable() | ||||||
| export default class extends Endpoint<typeof meta, typeof paramDef> { | export default class extends Endpoint<'drive/files/create'> { | ||||||
|  | 	name = 'drive/files/create' as const; | ||||||
| 	constructor( | 	constructor( | ||||||
| 		@Inject(DI.driveFilesRepository) | 		@Inject(DI.driveFilesRepository) | ||||||
| 		private driveFilesRepository: DriveFilesRepository, | 		private driveFilesRepository: DriveFilesRepository, | ||||||
| @@ -78,7 +21,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||||||
| 		private metaService: MetaService, | 		private metaService: MetaService, | ||||||
| 		private driveService: DriveService, | 		private driveService: DriveService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me, _, file, cleanup, ip, headers) => { | 		super(async (ps, me, _, file, cleanup, ip, headers) => { | ||||||
|  | 			if (ps.comment != null && ps.comment.length > DB_MAX_IMAGE_COMMENT_LENGTH) { | ||||||
|  | 				throw new ApiError(this.meta.errors.commentTooLong); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			// Get 'name' parameter | 			// Get 'name' parameter | ||||||
| 			let name = ps.name ?? file!.name ?? null; | 			let name = ps.name ?? file!.name ?? null; | ||||||
| 			if (name != null) { | 			if (name != null) { | ||||||
| @@ -88,7 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||||||
| 				} else if (name === 'blob') { | 				} else if (name === 'blob') { | ||||||
| 					name = null; | 					name = null; | ||||||
| 				} else if (!this.driveFileEntityService.validateFileName(name)) { | 				} else if (!this.driveFileEntityService.validateFileName(name)) { | ||||||
| 					throw new ApiError(meta.errors.invalidFileName); | 					throw new ApiError(this.meta.errors.invalidFileName); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -113,8 +60,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||||||
| 					console.error(err); | 					console.error(err); | ||||||
| 				} | 				} | ||||||
| 				if (err instanceof IdentifiableError) { | 				if (err instanceof IdentifiableError) { | ||||||
| 					if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate); | 					if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(this.meta.errors.inappropriate); | ||||||
| 					if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace); | 					if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(this.meta.errors.noFreeSpace); | ||||||
| 				} | 				} | ||||||
| 				throw new ApiError(); | 				throw new ApiError(); | ||||||
| 			} finally { | 			} finally { | ||||||
|   | |||||||
| @@ -3568,6 +3568,132 @@ export const endpoints = { | |||||||
| 		}] | 		}] | ||||||
| 	}, | 	}, | ||||||
| 	//#endregion | 	//#endregion | ||||||
|  |  | ||||||
|  | 	//#region drive | ||||||
|  | 	'drive/files/attached-notes': { | ||||||
|  | 		tags: ['drive', 'notes'], | ||||||
|  | 	 | ||||||
|  | 		requireCredential: true, | ||||||
|  | 	 | ||||||
|  | 		kind: 'read:drive', | ||||||
|  | 	 | ||||||
|  | 		description: 'Find the notes to which the given file is attached.', | ||||||
|  |  | ||||||
|  | 		errors: { | ||||||
|  | 			noSuchFile: { | ||||||
|  | 				message: 'No such file.', | ||||||
|  | 				code: 'NO_SUCH_FILE', | ||||||
|  | 				id: 'c118ece3-2e4b-4296-99d1-51756e32d232', | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		defines: [{ | ||||||
|  | 			req: { | ||||||
|  | 				type: 'object', | ||||||
|  | 				properties: { | ||||||
|  | 					fileId: { type: 'string', format: 'misskey:id' }, | ||||||
|  | 				}, | ||||||
|  | 				required: ['fileId'], | ||||||
|  | 			}, | ||||||
|  | 			res: { | ||||||
|  | 				type: 'array', | ||||||
|  | 				items: { | ||||||
|  | 					$ref: 'https://misskey-hub.net/api/schemas/Note', | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}], | ||||||
|  | 	}, | ||||||
|  | 	'drive/files/check-existence': { | ||||||
|  | 		tags: ['drive'], | ||||||
|  | 	 | ||||||
|  | 		requireCredential: true, | ||||||
|  | 	 | ||||||
|  | 		kind: 'read:drive', | ||||||
|  | 	 | ||||||
|  | 		description: 'Check if a given file exists.', | ||||||
|  | 	 | ||||||
|  | 		defines: [{ | ||||||
|  | 			req: { | ||||||
|  | 				type: 'object', | ||||||
|  | 				properties: { | ||||||
|  | 					md5: { type: 'string' }, | ||||||
|  | 				}, | ||||||
|  | 				required: ['md5'], | ||||||
|  | 			}, | ||||||
|  | 			res: { | ||||||
|  | 				type: 'boolean', | ||||||
|  | 			}, | ||||||
|  | 		}], | ||||||
|  | 	}, | ||||||
|  | 	'drive/files/create': { | ||||||
|  | 		tags: ['drive'], | ||||||
|  | 	 | ||||||
|  | 		requireCredential: true, | ||||||
|  | 	 | ||||||
|  | 		prohibitMoved: true, | ||||||
|  | 	 | ||||||
|  | 		limit: { | ||||||
|  | 			duration: ms('1hour'), | ||||||
|  | 			max: 120, | ||||||
|  | 		}, | ||||||
|  | 	 | ||||||
|  | 		requireFile: true, | ||||||
|  | 	 | ||||||
|  | 		kind: 'write:drive', | ||||||
|  | 	 | ||||||
|  | 		description: 'Upload a new drive file.', | ||||||
|  |  | ||||||
|  | 		errors: { | ||||||
|  | 			invalidFileName: { | ||||||
|  | 				message: 'Invalid file name.', | ||||||
|  | 				code: 'INVALID_FILE_NAME', | ||||||
|  | 				id: 'f449b209-0c60-4e51-84d5-29486263bfd4', | ||||||
|  | 			}, | ||||||
|  | 	 | ||||||
|  | 			inappropriate: { | ||||||
|  | 				message: 'Cannot upload the file because it has been determined that it possibly contains inappropriate content.', | ||||||
|  | 				code: 'INAPPROPRIATE', | ||||||
|  | 				id: 'bec5bd69-fba3-43c9-b4fb-2894b66ad5d2', | ||||||
|  | 			}, | ||||||
|  | 	 | ||||||
|  | 			noFreeSpace: { | ||||||
|  | 				message: 'Cannot upload the file because you have no free space of drive.', | ||||||
|  | 				code: 'NO_FREE_SPACE', | ||||||
|  | 				id: 'd08dbc37-a6a9-463a-8c47-96c32ab5f064', | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			commentTooLong: { | ||||||
|  | 				message: 'Comment is too long.', | ||||||
|  | 				code: 'COMMENT_TOO_LONG', | ||||||
|  | 				id: 'f0b0f2a0-0b0a-4b0a-8b0a-0b0a0b0a0b0a', | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		defines: [{ | ||||||
|  | 			req: { | ||||||
|  | 				type: 'object', | ||||||
|  | 				properties: { | ||||||
|  | 					file: { type: 'binary' }, | ||||||
|  | 					folderId: { | ||||||
|  | 						oneOf: [ | ||||||
|  | 							{ type: 'string', format: 'misskey:id' }, | ||||||
|  | 							{ type: 'null' }, | ||||||
|  | 						], | ||||||
|  | 						default: null, | ||||||
|  | 					}, | ||||||
|  | 					name: { type: ['string', 'null'], default: null }, | ||||||
|  | 					comment: { type: ['string', 'null'], default: null }, | ||||||
|  | 					isSensitive: { type: 'boolean', default: false }, | ||||||
|  | 					force: { type: 'boolean', default: false }, | ||||||
|  | 				}, | ||||||
|  | 				required: ['file'], | ||||||
|  | 			}, | ||||||
|  | 			res: { | ||||||
|  | 				$ref: 'https://misskey-hub.net/api/schemas/DriveFile', | ||||||
|  | 			}, | ||||||
|  | 		}], | ||||||
|  | 	}, | ||||||
|  | 	//#endregion | ||||||
| } as const satisfies { [x: string]: IEndpointMeta; }; | } as const satisfies { [x: string]: IEndpointMeta; }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 tamaina
					tamaina