This commit is contained in:
tamaina 2023-06-05 07:49:39 +00:00
parent b532ad8cd4
commit ced5638b80
4 changed files with 143 additions and 127 deletions

View file

@ -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')

View file

@ -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,

View file

@ -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 {

View file

@ -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; };
/** /**