wip
This commit is contained in:
parent
b532ad8cd4
commit
ced5638b80
4 changed files with 143 additions and 127 deletions
|
@ -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; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue