drive/folders

This commit is contained in:
tamaina 2023-06-16 06:49:29 +00:00
parent 028e7c00ae
commit ab02fd3ec4
6 changed files with 199 additions and 185 deletions

View file

@ -8,45 +8,10 @@ import { GlobalEventService } from '@/core/GlobalEventService.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,
kind: 'write:drive',
limit: {
duration: ms('1hour'),
max: 10,
},
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '53326628-a00d-40a6-a3cd-8975105c0f95',
},
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'DriveFolder',
},
} as const;
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', default: 'Untitled', maxLength: 200 },
parentId: { type: 'string', format: 'misskey:id', nullable: true },
},
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/folders/create'> {
name = 'drive/folders/create' as const;
constructor( constructor(
@Inject(DI.driveFoldersRepository) @Inject(DI.driveFoldersRepository)
private driveFoldersRepository: DriveFoldersRepository, private driveFoldersRepository: DriveFoldersRepository,
@ -55,7 +20,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private idService: IdService, private idService: IdService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
// If the parent folder is specified // If the parent folder is specified
let parent = null; let parent = null;
if (ps.parentId) { if (ps.parentId) {
@ -66,7 +31,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (parent == null) { if (parent == null) {
throw new ApiError(meta.errors.noSuchFolder); throw new ApiError(this.meta.errors.noSuchFolder);
} }
} }

View file

@ -5,39 +5,10 @@ import { GlobalEventService } from '@/core/GlobalEventService.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,
kind: 'write:drive',
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '1069098f-c281-440f-b085-f9932edbe091',
},
hasChildFilesOrFolders: {
message: 'This folder has child files or folders.',
code: 'HAS_CHILD_FILES_OR_FOLDERS',
id: 'b0fc8a17-963c-405d-bfbc-859a487295e1',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
},
required: ['folderId'],
} 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/folders/delete'> {
name = 'drive/folders/delete' as const;
constructor( constructor(
@Inject(DI.driveFilesRepository) @Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository, private driveFilesRepository: DriveFilesRepository,
@ -47,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
// Get folder // Get folder
const folder = await this.driveFoldersRepository.findOneBy({ const folder = await this.driveFoldersRepository.findOneBy({
id: ps.folderId, id: ps.folderId,
@ -55,7 +26,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (folder == null) { if (folder == null) {
throw new ApiError(meta.errors.noSuchFolder); throw new ApiError(this.meta.errors.noSuchFolder);
} }
const [childFoldersCount, childFilesCount] = await Promise.all([ const [childFoldersCount, childFilesCount] = await Promise.all([
@ -64,7 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
]); ]);
if (childFoldersCount !== 0 || childFilesCount !== 0) { if (childFoldersCount !== 0 || childFilesCount !== 0) {
throw new ApiError(meta.errors.hasChildFilesOrFolders); throw new ApiError(this.meta.errors.hasChildFilesOrFolders);
} }
await this.driveFoldersRepository.delete(folder.id); await this.driveFoldersRepository.delete(folder.id);

View file

@ -5,43 +5,17 @@ import type { DriveFoldersRepository } from '@/models/index.js';
import { DriveFolderEntityService } from '@/core/entities/DriveFolderEntityService.js'; import { DriveFolderEntityService } from '@/core/entities/DriveFolderEntityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['drive'],
requireCredential: true,
kind: 'read:drive',
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFolder',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string' },
parentId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
},
required: ['name'],
} 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/folders/find'> {
name = 'drive/folders/find' as const;
constructor( constructor(
@Inject(DI.driveFoldersRepository) @Inject(DI.driveFoldersRepository)
private driveFoldersRepository: DriveFoldersRepository, private driveFoldersRepository: DriveFoldersRepository,
private driveFolderEntityService: DriveFolderEntityService, private driveFolderEntityService: DriveFolderEntityService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const folders = await this.driveFoldersRepository.findBy({ const folders = await this.driveFoldersRepository.findBy({
name: ps.name, name: ps.name,
userId: me.id, userId: me.id,

View file

@ -5,46 +5,17 @@ import { DriveFolderEntityService } from '@/core/entities/DriveFolderEntityServi
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,
kind: 'read:drive',
res: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFolder',
},
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
},
required: ['folderId'],
} 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/folders/show'> {
name = 'drive/folders/show' as const;
constructor( constructor(
@Inject(DI.driveFoldersRepository) @Inject(DI.driveFoldersRepository)
private driveFoldersRepository: DriveFoldersRepository, private driveFoldersRepository: DriveFoldersRepository,
private driveFolderEntityService: DriveFolderEntityService, private driveFolderEntityService: DriveFolderEntityService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
// Get folder // Get folder
const folder = await this.driveFoldersRepository.findOneBy({ const folder = await this.driveFoldersRepository.findOneBy({
id: ps.folderId, id: ps.folderId,
@ -52,7 +23,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (folder == null) { if (folder == null) {
throw new ApiError(meta.errors.noSuchFolder); throw new ApiError(this.meta.errors.noSuchFolder);
} }
return await this.driveFolderEntityService.pack(folder, { return await this.driveFolderEntityService.pack(folder, {

View file

@ -6,53 +6,10 @@ import { GlobalEventService } from '@/core/GlobalEventService.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,
kind: 'write:drive',
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e',
},
noSuchParentFolder: {
message: 'No such parent folder.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
},
recursiveNesting: {
message: 'It can not be structured like nesting folders recursively.',
code: 'RECURSIVE_NESTING',
id: 'dbeb024837894013aed44279f9199740',
},
},
res: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFolder',
},
} as const;
export const paramDef = {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', maxLength: 200 },
parentId: { type: 'string', format: 'misskey:id', nullable: true },
},
required: ['folderId'],
} 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/folders/update'> {
name = 'drive/folders/update' as const;
constructor( constructor(
@Inject(DI.driveFoldersRepository) @Inject(DI.driveFoldersRepository)
private driveFoldersRepository: DriveFoldersRepository, private driveFoldersRepository: DriveFoldersRepository,
@ -60,7 +17,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private driveFolderEntityService: DriveFolderEntityService, private driveFolderEntityService: DriveFolderEntityService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
// Fetch folder // Fetch folder
const folder = await this.driveFoldersRepository.findOneBy({ const folder = await this.driveFoldersRepository.findOneBy({
id: ps.folderId, id: ps.folderId,
@ -68,14 +25,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (folder == null) { if (folder == null) {
throw new ApiError(meta.errors.noSuchFolder); throw new ApiError(this.meta.errors.noSuchFolder);
} }
if (ps.name) folder.name = ps.name; if (ps.name) folder.name = ps.name;
if (ps.parentId !== undefined) { if (ps.parentId !== undefined) {
if (ps.parentId === folder.id) { if (ps.parentId === folder.id) {
throw new ApiError(meta.errors.recursiveNesting); throw new ApiError(this.meta.errors.recursiveNesting);
} else if (ps.parentId === null) { } else if (ps.parentId === null) {
folder.parentId = null; folder.parentId = null;
} else { } else {
@ -86,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (parent == null) { if (parent == null) {
throw new ApiError(meta.errors.noSuchParentFolder); throw new ApiError(this.meta.errors.noSuchParentFolder);
} }
// Check if the circular reference will occur // Check if the circular reference will occur
@ -107,7 +64,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (parent.parentId !== null) { if (parent.parentId !== null) {
if (await checkCircle(parent.parentId)) { if (await checkCircle(parent.parentId)) {
throw new ApiError(meta.errors.recursiveNesting); throw new ApiError(this.meta.errors.recursiveNesting);
} }
} }

View file

@ -3914,6 +3914,182 @@ export const endpoints = {
res: undefined, res: undefined,
}], }],
}, },
'drive/folders/create': {
tags: ['drive'],
requireCredential: true,
kind: 'write:drive',
limit: {
duration: ms('1hour'),
max: 10,
},
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '53326628-a00d-40a6-a3cd-8975105c0f95',
},
},
defines: [{
req: {
type: 'object',
properties: {
name: { type: 'string', default: 'Untitled', maxLength: 200 },
parentId: {
oneOf: [
{ type: 'string', format: 'misskey:id' },
{ type: 'null' },
],
},
},
required: [],
},
res: {
$ref: 'https://misskey-hub.net/api/schemas/DriveFolder',
},
}],
},
'drive/folders/delete': {
tags: ['drive'],
requireCredential: true,
kind: 'write:drive',
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '1069098f-c281-440f-b085-f9932edbe091',
},
hasChildFilesOrFolders: {
message: 'This folder has child files or folders.',
code: 'HAS_CHILD_FILES_OR_FOLDERS',
id: 'b0fc8a17-963c-405d-bfbc-859a487295e1',
},
},
defines: [{
req: {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
},
required: ['folderId'],
},
res: undefined,
}],
},
'drive/folders/find': {
tags: ['drive'],
requireCredential: true,
kind: 'read:drive',
defines: [{
req: {
type: 'object',
properties: {
name: { type: 'string' },
parentId: {
oneOf: [
{ type: 'string', format: 'misskey:id' },
{ type: 'null' },
],
default: null,
},
},
required: ['name'],
},
res: {
type: 'array',
items: {
$ref: 'https://misskey-hub.net/api/schemas/DriveFolder',
},
}
}]
},
'drive/folders/show': {
tags: ['drive'],
requireCredential: true,
kind: 'read:drive',
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9',
},
},
defines: [{
req: {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
},
required: ['folderId'],
},
res: {
$ref: 'https://misskey-hub.net/api/schemas/DriveFolder',
}
}],
},
'drive/folders/update': {
tags: ['drive'],
requireCredential: true,
kind: 'write:drive',
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e',
},
noSuchParentFolder: {
message: 'No such parent folder.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
},
recursiveNesting: {
message: 'It can not be structured like nesting folders recursively.',
code: 'RECURSIVE_NESTING',
id: 'dbeb024837894013aed44279f9199740',
},
},
defines: [{
req: {
type: 'object',
properties: {
folderId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', maxLength: 200 },
parentId: {
oneOf: [
{ type: 'string', format: 'misskey:id' },
{ type: 'null' },
],
},
},
required: ['folderId'],
},
res: {
$ref: 'https://misskey-hub.net/api/schemas/DriveFolder',
}
}],
},
//#endregion //#endregion
} as const satisfies { [x: string]: IEndpointMeta; }; } as const satisfies { [x: string]: IEndpointMeta; };