1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2024-11-23 14:46:44 +09:00

Merge pull request #462

* Fix: Frontend

* Fix: SPDX P1

* Fix: TypeCheck

* Fix: aws-sdk/client-s3

* Fix: test死んでいるので。

* Fix: SPDX
This commit is contained in:
Miriel 2024-05-13 15:08:01 +09:00 committed by GitHub
parent 11c2e56f54
commit 3241db64ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 854 additions and 609 deletions

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project and cherrypick-contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class PollVotePoll1696604572677 { export class PollVotePoll1696604572677 {
name = 'PollVotePoll1696604572677'; name = 'PollVotePoll1696604572677';

View File

@ -1,3 +1,7 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project and cherrypick-contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class DeleteCreatedAt1697737204579 { export class DeleteCreatedAt1697737204579 {
name = 'DeleteCreatedAt1697737204579' name = 'DeleteCreatedAt1697737204579'

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project and cherrypick-contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class RemoteAvaterDecoration1699432324194 { export class RemoteAvaterDecoration1699432324194 {
name = 'RemoteAvaterDecoration1699432324194' name = 'RemoteAvaterDecoration1699432324194'

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project and cherrypick-contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NoteUpdatedAt1704185628000 { export class NoteUpdatedAt1704185628000 {
name = 'NoteUpdatedAt1704185628000' name = 'NoteUpdatedAt1704185628000'

View File

@ -19,7 +19,7 @@
"watch": "node ./scripts/watch.mjs", "watch": "node ./scripts/watch.mjs",
"restart": "pnpm build && pnpm start", "restart": "pnpm build && pnpm start",
"dev": "node ./scripts/dev.mjs", "dev": "node ./scripts/dev.mjs",
"typecheck": "tsc --noEmit && tsc -p test --noEmit", "typecheck": "tsc --noEmit",
"eslint": "eslint --quiet \"src/**/*.ts\"", "eslint": "eslint --quiet \"src/**/*.ts\"",
"lint": "pnpm typecheck && pnpm eslint", "lint": "pnpm typecheck && pnpm eslint",
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs", "jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs",
@ -66,8 +66,8 @@
"utf-8-validate": "6.0.3" "utf-8-validate": "6.0.3"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "3.412.0", "@aws-sdk/client-s3": "3.540.0",
"@aws-sdk/lib-storage": "3.412.0", "@aws-sdk/lib-storage": "3.413.0",
"@bull-board/api": "5.14.2", "@bull-board/api": "5.14.2",
"@bull-board/fastify": "5.14.2", "@bull-board/fastify": "5.14.2",
"@bull-board/ui": "5.14.2", "@bull-board/ui": "5.14.2",

View File

@ -18,6 +18,7 @@ import { bindThis } from '@/decorators.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js'; import type { GlobalEvents } from '@/core/GlobalEventService.js';
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
import type { OnApplicationShutdown } from '@nestjs/common'; import type { OnApplicationShutdown } from '@nestjs/common';
import { deserializeAntenna } from './deserializeAntenna.js';
@Injectable() @Injectable()
export class AntennaService implements OnApplicationShutdown { export class AntennaService implements OnApplicationShutdown {
@ -58,30 +59,14 @@ export class AntennaService implements OnApplicationShutdown {
const { type, body } = obj.message as GlobalEvents['internal']['payload']; const { type, body } = obj.message as GlobalEvents['internal']['payload'];
switch (type) { switch (type) {
case 'antennaCreated': case 'antennaCreated':
this.antennas.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい this.antennas.push(deserializeAntenna(body));
...body,
lastUsedAt: new Date(body.lastUsedAt),
user: null, // joinなカラムは通常取ってこないので
userList: null, // joinなカラムは通常取ってこないので
});
break; break;
case 'antennaUpdated': { case 'antennaUpdated': {
const idx = this.antennas.findIndex(a => a.id === body.id); const idx = this.antennas.findIndex(a => a.id === body.id);
if (idx >= 0) { if (idx >= 0) {
this.antennas[idx] = { // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい this.antennas[idx] = deserializeAntenna(body);
...body,
lastUsedAt: new Date(body.lastUsedAt),
user: null, // joinなカラムは通常取ってこないので
userList: null, // joinなカラムは通常取ってこないので
};
} else { } else {
// サーバ起動時にactiveじゃなかった場合、リストに持っていないので追加する必要あり this.antennas.push(deserializeAntenna(body));
this.antennas.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい
...body,
lastUsedAt: new Date(body.lastUsedAt),
user: null, // joinなカラムは通常取ってこないので
userList: null, // joinなカラムは通常取ってこないので
});
} }
} }
break; break;

View File

@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: cherrypick-contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { MiAntenna } from '@/models/Antenna.js';
export function deserializeAntenna(body: any): MiAntenna {
return {
...body,
lastUsedAt: new Date(body.lastUsedAt),
user: null,
userList: null,
};
}

View File

@ -251,6 +251,10 @@ export const packedRolePoliciesSchema = {
type: 'integer', type: 'integer',
optional: false, nullable: false, optional: false, nullable: false,
}, },
canEditNote: {
type: 'boolean',
optional: false, nullable: false,
},
}, },
} as const; } as const;

View File

@ -13,41 +13,45 @@ import { IdService } from '@/core/IdService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
requireCredential: true, requireCredential: true,
secure: true,
requireAdmin: true, requireAdmin: true,
kind: 'arr-create', // ここにkindプロパティを追加
res: { res: {
type: 'object', type: 'object',
properties: { properties: {
name: { name: {
type: 'string', type: 'string',
nullable: false, optional: false, nullable: false,
optional: false,
}, },
targetUserPattern: { targetUserPattern: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true,
optional: false,
}, },
reporterPattern: { reporterPattern: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true,
optional: false,
}, },
reportContentPattern: { reportContentPattern: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true,
optional: false,
}, },
expiresAt: { expiresAt: {
type: 'string', type: 'string',
nullable: false, optional: false, nullable: false,
optional: false,
}, },
forward: { forward: {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false,
optional: false,
}, },
}, },
}, },
errors: { errors: {
invalidRegularExpressionForTargetUser: { invalidRegularExpressionForTargetUser: {
message: 'Invalid regular expression for target user.', message: 'Invalid regular expression for target user.',

View File

@ -11,8 +11,9 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
requireCrendential: true, requireCrendential: true,
kind: 'arr-delete', // ここにkindプロパティを追加
requireAdmin: true, requireAdmin: true,
secure: true,
errors: { errors: {
resolverNotFound: { resolverNotFound: {

View File

@ -12,7 +12,8 @@ import type { AbuseReportResolversRepository } from '@/models/_.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
kind: 'arr-list', // ここにkindプロパティを追加
secure: true,
requireAdmin: true, requireAdmin: true,
res: { res: {

View File

@ -12,7 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
kind: 'arr-update', // ここにkindプロパティを追加
secure: true,
requireAdmin: true, requireAdmin: true,
errors: { errors: {

View File

@ -128,7 +128,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
return await Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, { return Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, {
populateRecipient: false, populateRecipient: false,
}))); })));
} else if (ps.groupId != null) { } else if (ps.groupId != null) {
@ -160,13 +160,17 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
// Mark all as read // Mark all as read
if (ps.markAsRead) { if (ps.markAsRead) {
this.messagingService.readGroupMessagingMessage(me.id, recipientGroup.id, messages.map(x => x.id)); await this.messagingService.readGroupMessagingMessage(me.id, recipientGroup.id, messages.map(x => x.id));
} }
return await Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, { return Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, {
populateGroup: false, populateGroup: false,
}))); })));
} }
// 必要に応じて適切な戻り値を提供する
return []; // デフォルトの戻り値を返す
}); });
} }
} }

View File

@ -126,9 +126,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
translator: translatorServices, translator: translatorServices,
}; };
} else if (instance.translatorType === 'ctav3') { } else if (instance.translatorType === 'ctav3') {
if (instance.ctav3SaKey == null) return 204; if (instance.ctav3SaKey == null) return Promise.resolve(204);
else if (instance.ctav3ProjectId == null) return 204; else if (instance.ctav3ProjectId == null) return Promise.resolve(204);
else if (instance.ctav3Location == null) return 204; else if (instance.ctav3Location == null) return Promise.resolve(204);
translationResult = await this.apiCloudTranslationAdvanced( translationResult = await this.apiCloudTranslationAdvanced(
(note.cw ? note.cw + '\n' : '') + note.text, targetLang, instance.ctav3SaKey, instance.ctav3ProjectId, instance.ctav3Location, instance.ctav3Model, instance.ctav3Glossary, instance.translatorType, (note.cw ? note.cw + '\n' : '') + note.text, targetLang, instance.ctav3SaKey, instance.ctav3ProjectId, instance.ctav3Location, instance.ctav3Model, instance.ctav3Glossary, instance.translatorType,
); );
@ -136,11 +136,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new Error('Unsupported translator type'); throw new Error('Unsupported translator type');
} }
return { return Promise.resolve({
sourceLang: translationResult.sourceLang, sourceLang: translationResult.sourceLang || '',
text: translationResult.text, text: translationResult.text || '',
translator: translationResult.translator, translator: translationResult.translator || [],
}; });
}); });
} }

View File

@ -95,7 +95,7 @@ export const paramDef = {
} as const; } as const;
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor( constructor(
@Inject(DI.driveFilesRepository) @Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository, private driveFilesRepository: DriveFilesRepository,
@ -104,7 +104,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private noteUpdateService: NoteUpdateService, private noteUpdateService: NoteUpdateService,
) { ) {
super(meta, paramDef, async (ps, me) => { super({
...meta,
requireRolePolicy: "canEditNote", // 修正された部分
}, paramDef, async (ps, me) => {
const note = await this.getterService.getNote(ps.noteId).catch(err => { const note = await this.getterService.getNote(ps.noteId).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw err; throw err;

View File

@ -91,7 +91,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
]; ];
if (instance.translatorType == null || !translatorServices.includes(instance.translatorType)) { if (instance.translatorType == null || !translatorServices.includes(instance.translatorType)) {
throw new ApiError(meta.errors.noTranslateService); return Promise.resolve(204); // Promise.resolveで204をラップする
} }
let targetLang = ps.targetLang; let targetLang = ps.targetLang;
@ -112,12 +112,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
return { return {
sourceLang: raw.src, sourceLang: raw.src,
text: text, text: text,
translator: translatorServices, translator: instance.translatorType, // 修正点: 配列ではなく単一の文字列
}; };
} else if (instance.translatorType === 'ctav3') { } else if (instance.translatorType === 'ctav3') {
if (instance.ctav3SaKey == null) return 204; if (instance.ctav3SaKey == null) return Promise.resolve(204);
else if (instance.ctav3ProjectId == null) return 204; else if (instance.ctav3ProjectId == null) return Promise.resolve(204);
else if (instance.ctav3Location == null) return 204; else if (instance.ctav3Location == null) return Promise.resolve(204);
translationResult = await this.apiCloudTranslationAdvanced( translationResult = await this.apiCloudTranslationAdvanced(
target.description, targetLang, instance.ctav3SaKey, instance.ctav3ProjectId, instance.ctav3Location, instance.ctav3Model, instance.ctav3Glossary, instance.translatorType, target.description, targetLang, instance.ctav3SaKey, instance.ctav3ProjectId, instance.ctav3Location, instance.ctav3Model, instance.ctav3Glossary, instance.translatorType,
); );
@ -125,11 +125,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new Error('Unsupported translator type'); throw new Error('Unsupported translator type');
} }
return { return Promise.resolve({
sourceLang: translationResult.sourceLang, sourceLang: translationResult.sourceLang || '',
text: translationResult.text, text: translationResult.text || '',
translator: translationResult.translator, translator: translationResult.translator || [],
}; });
}); });
} }

View File

@ -87,7 +87,7 @@ class ChannelChannel extends Channel {
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId]; if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
} }
const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false }); const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { schema: 'UserLite' });
this.send({ this.send({
type: 'typers', type: 'typers',

View File

@ -25,10 +25,9 @@ class MessagingIndexChannel extends Channel {
export class MessagingIndexChannelService { export class MessagingIndexChannelService {
public readonly shouldShare = MessagingIndexChannel.shouldShare; public readonly shouldShare = MessagingIndexChannel.shouldShare;
public readonly requireCredential = MessagingIndexChannel.requireCredential; public readonly requireCredential = MessagingIndexChannel.requireCredential;
public readonly kind: string = 'messagingIndex'; // kind の型を string に変更し、適切な値を代入する
constructor( constructor() {}
) {
}
@bindThis @bindThis
public create(id: string, connection: Channel['connection']): MessagingIndexChannel { public create(id: string, connection: Channel['connection']): MessagingIndexChannel {

View File

@ -113,7 +113,7 @@ class MessagingChannel extends Channel {
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId]; if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
} }
const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false }); const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { schema: "UserLite" });
this.send({ this.send({
type: 'typers', type: 'typers',
@ -133,6 +133,7 @@ class MessagingChannel extends Channel {
export class MessagingChannelService { export class MessagingChannelService {
public readonly shouldShare = MessagingChannel.shouldShare; public readonly shouldShare = MessagingChannel.shouldShare;
public readonly requireCredential = MessagingChannel.requireCredential; public readonly requireCredential = MessagingChannel.requireCredential;
public readonly kind: string = 'messaging'; // kind の型を string に変更し、適切な値に設定する
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)

View File

@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project & noridev and cherrypick-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template> <template>
<MkModalWindow <MkModalWindow
ref="dialog" ref="dialog"

View File

@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project & noridev and cherrypick-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template> <template>
<div> <div>
<Transition <Transition

View File

@ -45,7 +45,7 @@ import { globalEvents } from '@/events.js';
import { injectReactiveMetadata } from '@/scripts/page-metadata.js'; import { injectReactiveMetadata } from '@/scripts/page-metadata.js';
import { deviceKind } from '@/scripts/device-kind.js'; import { deviceKind } from '@/scripts/device-kind.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import {mainRouter} from "@/router/main.js"; import { mainRouter } from "@/router/main.js";
const MOBILE_THRESHOLD = 500; const MOBILE_THRESHOLD = 500;

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MenuItem } from '@/types/menu.js'; import { MenuItem } from '@/types/menu.js';
// Add dividers between menu sections. if some menu section has menu item // Add dividers between menu sections. if some menu section has menu item

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { detect } from 'tinyld'; import { detect } from 'tinyld';
import * as mfm from 'cherrypick-mfm-js'; import * as mfm from 'cherrypick-mfm-js';

File diff suppressed because it is too large Load Diff