diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 6e69b3b11..4f4f2c16f 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -105,6 +105,7 @@ import * as ep___clips_show from './endpoints/clips/show.js'; import * as ep___clips_update from './endpoints/clips/update.js'; import * as ep___drive from './endpoints/drive.js'; import * as ep___drive_files from './endpoints/drive/files.js'; +import * as ep___drive_show from './endpoints/drive/show.js'; import * as ep___drive_files_attachedNotes from './endpoints/drive/files/attached-notes.js'; import * as ep___drive_files_checkExistence from './endpoints/drive/files/check-existence.js'; import * as ep___drive_files_create from './endpoints/drive/files/create.js'; @@ -414,6 +415,7 @@ const eps = [ ['clips/update', ep___clips_update], ['drive', ep___drive], ['drive/files', ep___drive_files], + ['drive/show', ep___drive_show], ['drive/files/attached-notes', ep___drive_files_attachedNotes], ['drive/files/check-existence', ep___drive_files_checkExistence], ['drive/files/create', ep___drive_files_create], diff --git a/packages/backend/src/server/api/endpoints/drive/show.ts b/packages/backend/src/server/api/endpoints/drive/show.ts new file mode 100644 index 000000000..3d88ed5f5 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/drive/show.ts @@ -0,0 +1,70 @@ +import { DriveFiles, DriveFolders } from '@/models/index.js'; +import define from '../../define.js'; +import { makePaginationQuery } from '../../common/make-pagination-query.js'; + +export const meta = { + tags: ['drive'], + + description: "Lists all folders and files in the authenticated user's drive. Folders are always listed first. The limit, if specified, is applied over the total number of elements.", + + requireCredential: true, + + kind: 'read:drive', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + oneOf: [{ + type: 'object', + optional: false, nullable: false, + ref: 'DriveFile', + }, { + type: 'object', + optional: false, nullable: false, + ref: 'DriveFolder', + }], + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, + }, + required: [], +} as const; + +// eslint-disable-next-line import/no-default-export +export default define(meta, paramDef, async (ps, user) => { + const foldersQuery = makePaginationQuery(DriveFolders.createQueryBuilder('folder'), ps.sinceId, ps.untilId) + .andWhere('folder.userId = :userId', { userId: user.id }); + const filesQuery = makePaginationQuery(DriveFiles.createQueryBuilder('file'), ps.sinceId, ps.untilId) + .andWhere('file.userId = :userId', { userId: user.id }); + + if (ps.folderId) { + foldersQuery.andWhere('folder.parentId = :parentId', { parentId: ps.folderId }); + filesQuery.andWhere('file.folderId = :folderId', { folderId: ps.folderId }); + } else { + foldersQuery.andWhere('folder.parentId IS NULL'); + filesQuery.andWhere('file.folderId IS NULL'); + } + + const folders = await foldersQuery.take(ps.limit).getMany(); + + const [files, ...packedFolders] = await Promise.all([ + filesQuery.take(ps.limit - folders.length).getMany(), + ...(folders.map(folder => DriveFolders.pack(folder))), + ]); + + const packedFiles = await DriveFiles.packMany(files, { detail: false, self: true }); + + return [ + ...packedFolders, + ...packedFiles, + ]; +});