This commit is contained in:
tamaina 2023-05-22 01:43:00 +00:00
parent 8adf2701d2
commit 810d065d21
19 changed files with 144 additions and 543 deletions

View file

@ -6,6 +6,7 @@ import { ApiError } from './error.js';
import { endpoints } from 'misskey-js/built/endpoints.js';
import type { IEndpointMeta, ResponseOf, SchemaOrUndefined } from 'misskey-js/built/endpoints.types.js';
import type { Endpoints } from 'misskey-js';
import { WeakSerialized } from 'schema-type';
const ajv = new Ajv({
useDefaults: true,
@ -29,7 +30,7 @@ export type Executor<T extends IEndpointMeta, P = SchemaOrUndefined<T['defines']
cleanup?: () => any,
ip?: string | null,
headers?: Record<string, string> | null
) => Promise<ResponseOf<T, P>>;
) => Promise<WeakSerialized<ResponseOf<T, P>>>;
// ExecutorWrapperの型はあえて緩くしておく
export type ExecutorWrapper =

View file

@ -7,34 +7,10 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { localUsernameSchema, passwordSchema } from '@/models/entities/User.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
res: {
type: 'object',
optional: false, nullable: false,
ref: 'User',
properties: {
token: {
type: 'string',
optional: false, nullable: false,
},
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
username: localUsernameSchema,
password: passwordSchema,
},
required: ['username', 'password'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/accounts/create'> {
name = 'admin/accounts/create' as const;
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@ -42,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private userEntityService: UserEntityService,
private signupService: SignupService,
) {
super(meta, paramDef, async (ps, _me) => {
super(async (ps, _me) => {
const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null;
const noUsers = (await this.usersRepository.countBy({
host: IsNull(),
@ -55,14 +31,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
ignorePreservedUsernames: true,
});
const res = await this.userEntityService.pack(account, account, {
const res = await this.userEntityService.pack<true, true>(account, account, {
detail: true,
includeSecrets: true,
});
(res as any).token = secret;
return res;
return { ...res, token: secret };
});
}
}

View file

@ -7,24 +7,10 @@ import { UserSuspendService } from '@/core/UserSuspendService.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireAdmin: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/accounts/delete'> {
name = 'admin/accounts/delete' as const;
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@ -34,7 +20,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private globalEventService: GlobalEventService,
private userSuspendService: UserSuspendService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) {

View file

@ -4,38 +4,17 @@ import type { AdsRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
url: { type: 'string', minLength: 1 },
memo: { type: 'string' },
place: { type: 'string' },
priority: { type: 'string' },
ratio: { type: 'integer' },
expiresAt: { type: 'integer' },
startsAt: { type: 'integer' },
imageUrl: { type: 'string', minLength: 1 },
},
required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/ad/create'> {
name = 'admin/ad/create' as const;
constructor(
@Inject(DI.adsRepository)
private adsRepository: AdsRepository,
private idService: IdService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
await this.adsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),

View file

@ -4,40 +4,18 @@ import type { AdsRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
errors: {
noSuchAd: {
message: 'No such ad.',
code: 'NO_SUCH_AD',
id: 'ccac9863-3a03-416e-b899-8a64041118b1',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
},
required: ['id'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/ad/delete'> {
name = 'admin/ad/delete' as const;
constructor(
@Inject(DI.adsRepository)
private adsRepository: AdsRepository,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const ad = await this.adsRepository.findOneBy({ id: ps.id });
if (ad == null) throw new ApiError(meta.errors.noSuchAd);
if (ad == null) throw new ApiError(this.meta.errors.noSuchAd);
await this.adsRepository.delete(ad.id);
});

View file

@ -23,14 +23,15 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/ad/list'> {
name = 'admin/ad/list' as const;
constructor(
@Inject(DI.adsRepository)
private adsRepository: AdsRepository,
private queryService: QueryService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId);
const ads = await query.take(ps.limit).getMany();

View file

@ -4,37 +4,6 @@ import type { AdsRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
errors: {
noSuchAd: {
message: 'No such ad.',
code: 'NO_SUCH_AD',
id: 'b7aa1727-1354-47bc-a182-3a9c3973d300',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
memo: { type: 'string' },
url: { type: 'string', minLength: 1 },
imageUrl: { type: 'string', minLength: 1 },
place: { type: 'string' },
priority: { type: 'string' },
ratio: { type: 'integer' },
expiresAt: { type: 'integer' },
startsAt: { type: 'integer' },
},
required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<'admin/ad/update'> {

View file

@ -4,68 +4,17 @@ import type { AnnouncementsRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
res: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
title: {
type: 'string',
optional: false, nullable: false,
},
text: {
type: 'string',
optional: false, nullable: false,
},
imageUrl: {
type: 'string',
optional: false, nullable: true,
},
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
title: { type: 'string', minLength: 1 },
text: { type: 'string', minLength: 1 },
imageUrl: { type: 'string', nullable: true, minLength: 1 },
},
required: ['title', 'text', 'imageUrl'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/announcements/create'> {
name = 'admin/announcements/create' as const;
constructor(
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
private idService: IdService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const announcement = await this.announcementsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),

View file

@ -4,40 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
errors: {
noSuchAnnouncement: {
message: 'No such announcement.',
code: 'NO_SUCH_ANNOUNCEMENT',
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
},
required: ['id'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/announcements/delete'> {
name = 'admin/announcements/delete' as const;
constructor(
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const announcement = await this.announcementsRepository.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement);
await this.announcementsRepository.delete(announcement.id);
});

View file

@ -5,69 +5,10 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueryService } from '@/core/QueryService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
text: {
type: 'string',
optional: false, nullable: false,
},
title: {
type: 'string',
optional: false, nullable: false,
},
imageUrl: {
type: 'string',
optional: false, nullable: true,
},
reads: {
type: 'number',
optional: false, nullable: false,
},
},
},
},
} 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' },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/announcements/list'> {
name = 'admin/announcements/list' as const;
constructor(
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
@ -77,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private queryService: QueryService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
const announcements = await query.take(ps.limit).getMany();

View file

@ -4,43 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
errors: {
noSuchAnnouncement: {
message: 'No such announcement.',
code: 'NO_SUCH_ANNOUNCEMENT',
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
title: { type: 'string', minLength: 1 },
text: { type: 'string', minLength: 1 },
imageUrl: { type: 'string', nullable: true, minLength: 1 },
},
required: ['id', 'title', 'text', 'imageUrl'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/announcements/update'> {
name = 'admin/announcements/update' as const;
constructor(
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const announcement = await this.announcementsRepository.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement);
await this.announcementsRepository.update(announcement.id, {
updatedAt: new Date(),

View file

@ -2,26 +2,14 @@ import { Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
} as const;
export const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/drive/clean-remote-files'> {
name = 'admin/drive/clean-remote-files' as const;
constructor(
private queueService: QueueService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
this.queueService.createCleanRemoteFilesJob();
});
}

View file

@ -5,29 +5,17 @@ import type { DriveFilesRepository } from '@/models/index.js';
import { DriveService } from '@/core/DriveService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
} as const;
export const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/drive/cleanup'> {
name = 'admin/drive/cleanup' as const;
constructor(
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
private driveService: DriveService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const files = await this.driveFilesRepository.findBy({
userId: IsNull(),
});

View file

@ -5,45 +5,10 @@ import { QueryService } from '@/core/QueryService.js';
import { DI } from '@/di-symbols.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFile',
},
},
} 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' },
userId: { type: 'string', format: 'misskey:id', nullable: true },
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) },
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'local' },
hostname: {
type: 'string',
nullable: true,
default: null,
description: 'The local host is represented with `null`.',
},
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/drive/files'> {
name = 'admin/drive/files' as const;
constructor(
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
@ -51,7 +16,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private driveFileEntityService: DriveFileEntityService,
private queryService: QueryService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId);
if (ps.userId) {

View file

@ -5,152 +5,10 @@ import { DI } from '@/di-symbols.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
errors: {
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240',
},
},
res: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
userId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
userHost: {
type: 'string',
optional: false, nullable: true,
description: 'The local host is represented with `null`.',
},
md5: {
type: 'string',
optional: false, nullable: false,
format: 'md5',
example: '15eca7fba0480996e2245f5185bf39f2',
},
name: {
type: 'string',
optional: false, nullable: false,
example: 'lenna.jpg',
},
type: {
type: 'string',
optional: false, nullable: false,
example: 'image/jpeg',
},
size: {
type: 'number',
optional: false, nullable: false,
example: 51469,
},
comment: {
type: 'string',
optional: false, nullable: true,
},
blurhash: {
type: 'string',
optional: false, nullable: true,
},
properties: {
type: 'object',
optional: false, nullable: false,
},
storedInternal: {
type: 'boolean',
optional: false, nullable: true,
example: true,
},
url: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
thumbnailUrl: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
webpublicUrl: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
accessKey: {
type: 'string',
optional: false, nullable: true,
},
thumbnailAccessKey: {
type: 'string',
optional: false, nullable: true,
},
webpublicAccessKey: {
type: 'string',
optional: false, nullable: true,
},
uri: {
type: 'string',
optional: false, nullable: true,
},
src: {
type: 'string',
optional: false, nullable: true,
},
folderId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
isSensitive: {
type: 'boolean',
optional: false, nullable: false,
},
isLink: {
type: 'boolean',
optional: false, nullable: false,
},
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
fileId: { type: 'string', format: 'misskey:id' },
url: { type: 'string' },
},
anyOf: [
{ required: ['fileId'] },
{ required: ['url'] },
],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
export default class extends Endpoint<'admin/drive/show-file'> {
name = 'admin/drive/show-file' as const;
constructor(
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
@ -160,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
super(async (ps, me) => {
const file = ps.fileId ? await this.driveFilesRepository.findOneBy({ id: ps.fileId }) : await this.driveFilesRepository.findOne({
where: [{
url: ps.url,
@ -172,7 +30,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
});
if (file == null) {
throw new ApiError(meta.errors.noSuchFile);
throw new ApiError(this.meta.errors.noSuchFile);
}
const owner = file.userId ? await this.usersRepository.findOneByOrFail({

View file

@ -1,4 +1,5 @@
import type { Endpoints, SchemaOrUndefined, IEndpointMeta, ResponseOf } from './endpoints.types.js';
import type { Serialized, WeakSerialized } from 'schema-type';
const MK_API_ERROR = Symbol();
@ -42,9 +43,10 @@ export class APIClient {
this.fetch = opts.fetch ?? ((...args) => fetch(...args));
}
// WeakSerialized<P>で推論が効くかは知らない
public request<E extends keyof Endpoints, P extends SchemaOrUndefined<M['defines'][number]['req']>, M extends IEndpointMeta = Endpoints[E], R = ResponseOf<M, P>>(
endpoint: E, params: P, credential?: string | null | undefined,
): Promise<R>
endpoint: E, params: WeakSerialized<P>, credential?: string | null | undefined,
): Promise<Serialized<R>>
{
const promise = new Promise((resolve, reject) => {
this.fetch(`${this.origin}/api/${endpoint}`, {

View file

@ -269,7 +269,7 @@ export const endpoints = {
res: undefined,
}],
},
"admin/drive/clenaup": {
"admin/drive/cleanup": {
tags: ['admin'],
requireCredential: true,
@ -354,11 +354,56 @@ export const endpoints = {
],
},
res: {
allOf: [{
$ref: 'https://misskey-hub.net/api/schemas/DriveFile',
}, {
type: 'object',
properties: {
id: { $ref: 'https://misskey-hub.net/api/schemas/Id' },
createdAt: { type: 'string', format: 'date-time' },
userId: {
oneOf: [
{ $ref: 'https://misskey-hub.net/api/schemas/Id' },
{ type: 'null' },
]
},
userHost: { type: ['string', 'null'] },
md5: { type: 'string', format: 'md5', examples: '1bc29b36f623ba82aaf6724fd3b16718' },
name: { type: 'string', examples: 'lenna.jpg' },
type: { type: 'string', examples: 'image/jpeg' },
size: { type: 'number', examples: 51469 },
comment: { type: ['string', 'null'] },
blurhash: { type: ['string', 'null'] },
properties: { type: 'object' },
storedInternal: { type: ['boolean', 'null'], examples: true },
url: {
oneOf: [
{ type: 'string', format: 'url' },
{ type: 'null' },
],
},
thumbnailUrl: {
oneOf: [
{ type: 'string', format: 'url' },
{ type: 'null' },
],
},
webpublicUrl: {
oneOf: [
{ type: 'string', format: 'url' },
{ type: 'null' },
],
},
accessKey: { type: ['string', 'null'] },
thumbnailAccessKey: { type: ['string', 'null'] },
webpublicAccessKey: { type: ['string', 'null'] },
uri: { type: ['string', 'null'] },
src: { type: ['string', 'null'] },
folderId: {
oneOf: [
{ $ref: 'https://misskey-hub.net/api/schemas/Id' },
{ type: 'null' },
]
},
isSensitive: { type: 'boolean' },
isLink: { type: 'boolean' },
requestIp: {
type: ['string', 'null'],
},
@ -370,8 +415,33 @@ export const endpoints = {
}],
}
},
required: ['requestIp', 'requestHeaders'],
}],
required: [
'id',
'createdAt',
'userId',
'userHost',
'md5',
'name',
'type',
'size',
'comment',
'blurhash',
'properties',
'storedInternal',
'url',
'thumbnailUrl',
'webpublicUrl',
'accessKey',
'thumbnailAccessKey',
'webpublicAccessKey',
'uri',
'src',
'folderId',
'isSensitive',
'isLink',
'requestIp',
'requestHeaders',
],
},
}],
},

View file

@ -40,7 +40,6 @@ export const packedAdSchema = {
'expiresAt',
'startsAt',
'place',
'property',
'ratio',
'imageUrl',
'memo',

View file

@ -626,7 +626,7 @@ importers:
version: 29.5.0
schema-type:
specifier: github:misskey-dev/schema-type
version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4)
version: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4)
packages/frontend:
dependencies:
@ -1026,7 +1026,7 @@ importers:
version: 4.4.0
schema-type:
specifier: github:misskey-dev/schema-type
version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4)
version: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4)
ts-essentials:
specifier: ^9.3.2
version: 9.3.2(typescript@5.0.4)
@ -20455,9 +20455,9 @@ packages:
version: 0.0.0
dev: false
github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4):
resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/e24efd7bba40f638b3b687298873fa56de56aab3}
id: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3
github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4):
resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/3e1f60a3486ad51a01912bd7bb092d5bcf47473e}
id: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e
name: schema-type
version: 1.0.0
dependencies: