Merge remote-tracking branch 'misskey/master' into feature/misskey-2024.07

This commit is contained in:
dakkar 2024-08-02 12:25:58 +01:00
commit cfa9b852df
585 changed files with 23423 additions and 9623 deletions

View file

@ -1,8 +0,0 @@
node_modules
/built
/coverage
/.eslintrc.js
/jest.config.ts
/test
/test-d
build.js

View file

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../shared/.eslintrc.js',
],
};

View file

@ -154,5 +154,5 @@ stream.on('_disconnected_', () => {
---
<div align="center">
<a href="https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md"><img src="https://raw.githubusercontent.com/misskey-dev/assets/main/i-want-you.png" width="300"></a>
<a href="https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md"><img src="https://assets.misskey-hub.net/public/i-want-you.png" width="300"></a>
</div>

View file

@ -1,32 +1,32 @@
import * as esbuild from "esbuild";
import { build } from "esbuild";
import { globSync } from "glob";
import { execa } from "execa";
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import * as esbuild from 'esbuild';
import { build } from 'esbuild';
import { globSync } from 'glob';
import { execa } from 'execa';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8'));
const entryPoints = globSync("./src/**/**.{ts,tsx}");
const entryPoints = globSync('./src/**/**.{ts,tsx}');
/** @type {import('esbuild').BuildOptions} */
const options = {
entryPoints,
minify: process.env.NODE_ENV === 'production',
outdir: "./built",
target: "es2022",
platform: "browser",
format: "esm",
outdir: './built',
target: 'es2022',
platform: 'browser',
format: 'esm',
sourcemap: 'linked',
};
// built配下をすべて削除する
fs.rmSync('./built', { recursive: true, force: true });
if (process.argv.map(arg => arg.toLowerCase()).includes("--watch")) {
if (process.argv.map(arg => arg.toLowerCase()).includes('--watch')) {
await watchSrc();
} else {
await buildSrc();
@ -36,7 +36,7 @@ async function buildSrc() {
console.log(`[${_package.name}] start building...`);
await build(options)
.then(it => {
.then(() => {
console.log(`[${_package.name}] build succeeded.`);
})
.catch((err) => {
@ -65,7 +65,7 @@ function buildDts() {
{
stdout: process.stdout,
stderr: process.stderr,
}
},
);
}
@ -86,7 +86,7 @@ async function watchSrc() {
},
}];
console.log(`[${_package.name}] start watching...`)
console.log(`[${_package.name}] start watching...`);
const context = await esbuild.context({ ...options, plugins });
await context.watch();
@ -95,7 +95,6 @@ async function watchSrc() {
process.on('SIGHUP', resolve);
process.on('SIGINT', resolve);
process.on('SIGTERM', resolve);
process.on('SIGKILL', resolve);
process.on('uncaughtException', reject);
process.on('exit', resolve);
}).finally(async () => {

View file

@ -0,0 +1,29 @@
import tsParser from '@typescript-eslint/parser';
import sharedConfig from '../shared/eslint.config.js';
// eslint-disable-next-line import/no-default-export
export default [
...sharedConfig,
{
ignores: [
'**/node_modules',
'built',
'coverage',
'jest.config.ts',
'test',
'test-d',
'generator',
],
},
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parserOptions: {
parser: tsParser,
project: ['./tsconfig.json'],
sourceType: 'module',
tsconfigRootDir: import.meta.dirname,
},
},
},
];

View file

@ -6,6 +6,11 @@
import { EventEmitter } from 'eventemitter3';
// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type AbuseReportNotificationRecipient = components['schemas']['AbuseReportNotificationRecipient'];
// @public (undocumented)
export type Acct = {
username: string;
@ -21,13 +26,38 @@ declare namespace acct {
}
export { acct }
// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type Ad = components['schemas']['Ad'];
// Warning: (ae-forgotten-export) The symbol "operations" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type AdminAbuseReportNotificationRecipientCreateRequest = operations['admin___abuse-report___notification-recipient___create']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientCreateResponse = operations['admin___abuse-report___notification-recipient___create']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientDeleteRequest = operations['admin___abuse-report___notification-recipient___delete']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientListRequest = operations['admin___abuse-report___notification-recipient___list']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientListResponse = operations['admin___abuse-report___notification-recipient___list']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientShowRequest = operations['admin___abuse-report___notification-recipient___show']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientShowResponse = operations['admin___abuse-report___notification-recipient___show']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientUpdateRequest = operations['admin___abuse-report___notification-recipient___update']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminAbuseReportNotificationRecipientUpdateResponse = operations['admin___abuse-report___notification-recipient___update']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminAbuseUserReportsRequest = operations['admin___abuse-user-reports']['requestBody']['content']['application/json'];
@ -319,6 +349,33 @@ type AdminSuspendUserRequest = operations['admin___suspend-user']['requestBody']
// @public (undocumented)
type AdminUnnsfwUserRequest = operations['admin___unnsfw-user']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookCreateRequest = operations['admin___system-webhook___create']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookCreateResponse = operations['admin___system-webhook___create']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookDeleteRequest = operations['admin___system-webhook___delete']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookListRequest = operations['admin___system-webhook___list']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookListResponse = operations['admin___system-webhook___list']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookShowRequest = operations['admin___system-webhook___show']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookShowResponse = operations['admin___system-webhook___show']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookUpdateRequest = operations['admin___system-webhook___update']['requestBody']['content']['application/json'];
// @public (undocumented)
type AdminSystemWebhookUpdateResponse = operations['admin___system-webhook___update']['responses']['200']['content']['application/json'];
// @public (undocumented)
type AdminUnsetUserAvatarRequest = operations['admin___unset-user-avatar']['requestBody']['content']['application/json'];
@ -509,7 +566,7 @@ type Channel = components['schemas']['Channel'];
// Warning: (ae-forgotten-export) The symbol "AnyOf" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export abstract class ChannelConnection<Channel extends AnyOf<Channels> = any> extends EventEmitter<Channel['events']> {
export abstract class ChannelConnection<Channel extends AnyOf<Channels> = AnyOf<Channels>> extends EventEmitter<Channel['events']> {
constructor(stream: Stream, channel: string, name?: string);
// (undocumented)
channel: string;
@ -745,12 +802,12 @@ export type Channels = {
user1: boolean;
user2: boolean;
}) => void;
updateSettings: (payload: {
updateSettings: <K extends ReversiUpdateKey>(payload: {
userId: User['id'];
key: string;
value: any;
key: K;
value: ReversiGameDetailed[K];
}) => void;
log: (payload: Record<string, any>) => void;
log: (payload: Record<string, unknown>) => void;
};
receives: {
putStone: {
@ -759,10 +816,7 @@ export type Channels = {
};
ready: boolean;
cancel: null | Record<string, never>;
updateSettings: {
key: string;
value: any;
};
updateSettings: ReversiUpdateSettings<ReversiUpdateKey>;
claimTimeIsUp: null | Record<string, never>;
};
};
@ -1134,6 +1188,12 @@ export type Endpoints = Overwrite<Endpoints_2, {
req: SigninRequest;
res: SigninResponse;
};
'admin/roles/create': {
req: Overwrite<AdminRolesCreateRequest, {
policies: PartialRolePolicyOverride;
}>;
res: AdminRolesCreateResponse;
};
}>;
// @public (undocumented)
@ -1159,11 +1219,21 @@ declare namespace entities {
SignupPendingResponse,
SigninRequest,
SigninResponse,
PartialRolePolicyOverride,
EmptyRequest,
EmptyResponse,
AdminMetaResponse,
AdminAbuseUserReportsRequest,
AdminAbuseUserReportsResponse,
AdminAbuseReportNotificationRecipientListRequest,
AdminAbuseReportNotificationRecipientListResponse,
AdminAbuseReportNotificationRecipientShowRequest,
AdminAbuseReportNotificationRecipientShowResponse,
AdminAbuseReportNotificationRecipientCreateRequest,
AdminAbuseReportNotificationRecipientCreateResponse,
AdminAbuseReportNotificationRecipientUpdateRequest,
AdminAbuseReportNotificationRecipientUpdateResponse,
AdminAbuseReportNotificationRecipientDeleteRequest,
AdminAccountsCreateRequest,
AdminAccountsCreateResponse,
AdminAccountsDeleteRequest,
@ -1264,6 +1334,15 @@ declare namespace entities {
AdminRolesUpdateDefaultPoliciesRequest,
AdminRolesUsersRequest,
AdminRolesUsersResponse,
AdminSystemWebhookCreateRequest,
AdminSystemWebhookCreateResponse,
AdminSystemWebhookDeleteRequest,
AdminSystemWebhookListRequest,
AdminSystemWebhookListResponse,
AdminSystemWebhookShowRequest,
AdminSystemWebhookShowResponse,
AdminSystemWebhookUpdateRequest,
AdminSystemWebhookUpdateResponse,
AnnouncementsRequest,
AnnouncementsResponse,
AnnouncementsShowRequest,
@ -1779,7 +1858,9 @@ declare namespace entities {
ReversiGameDetailed,
MetaLite,
MetaDetailedOnly,
MetaDetailed
MetaDetailed,
SystemWebhook,
AbuseReportNotificationRecipient
}
}
export { entities }
@ -1838,7 +1919,7 @@ type FetchExternalResourcesResponse = operations['fetch-external-resources']['re
// @public (undocumented)
type FetchLike = (input: string, init?: {
method?: string;
body?: string;
body?: Blob | FormData | string;
credentials?: RequestCredentials;
cache?: RequestCache;
headers: {
@ -2435,12 +2516,27 @@ type ModerationLog = {
type: 'unsetUserAvatar';
info: ModerationLogPayloads['unsetUserAvatar'];
} | {
type: 'unsetUserBanner';
info: ModerationLogPayloads['unsetUserBanner'];
type: 'createSystemWebhook';
info: ModerationLogPayloads['createSystemWebhook'];
} | {
type: 'updateSystemWebhook';
info: ModerationLogPayloads['updateSystemWebhook'];
} | {
type: 'deleteSystemWebhook';
info: ModerationLogPayloads['deleteSystemWebhook'];
} | {
type: 'createAbuseReportNotificationRecipient';
info: ModerationLogPayloads['createAbuseReportNotificationRecipient'];
} | {
type: 'updateAbuseReportNotificationRecipient';
info: ModerationLogPayloads['updateAbuseReportNotificationRecipient'];
} | {
type: 'deleteAbuseReportNotificationRecipient';
info: ModerationLogPayloads['deleteAbuseReportNotificationRecipient'];
});
// @public (undocumented)
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "approve", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "updateRemoteInstanceNote", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "approve", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "updateRemoteInstanceNote", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner", "createSystemWebhook", "updateSystemWebhook", "deleteSystemWebhook", "createAbuseReportNotificationRecipient", "updateAbuseReportNotificationRecipient", "deleteAbuseReportNotificationRecipient"];
// @public (undocumented)
type MuteCreateRequest = operations['mute___create']['requestBody']['content']['application/json'];
@ -2707,7 +2803,16 @@ type PagesUnlikeRequest = operations['pages___unlike']['requestBody']['content']
type PagesUpdateRequest = operations['pages___update']['requestBody']['content']['application/json'];
// @public (undocumented)
function parse(acct: string): Acct;
function parse(_acct: string): Acct;
// Warning: (ae-forgotten-export) The symbol "Values" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type PartialRolePolicyOverride = Partial<{
[k in keyof RolePolicies]: Omit<Values<Role['policies']>, 'value'> & {
value: RolePolicies[k];
};
}>;
// @public (undocumented)
export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:channels", "write:channels", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "write:admin:suspend-user", "write:admin:approve-user", "write:admin:nsfw-user", "write:admin:unnsfw-user", "write:admin:silence-user", "write:admin:unsilence-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"];
@ -2940,7 +3045,7 @@ export class Stream extends EventEmitter<StreamEvents> {
constructor(origin: string, user: {
token: string;
} | null, options?: {
WebSocket?: any;
WebSocket?: WebSocket;
});
// (undocumented)
close(): void;
@ -2963,9 +3068,9 @@ export class Stream extends EventEmitter<StreamEvents> {
// (undocumented)
send(typeOrPayload: string): void;
// (undocumented)
send(typeOrPayload: string, payload: any): void;
send(typeOrPayload: string, payload: unknown): void;
// (undocumented)
send(typeOrPayload: Record<string, any> | any[]): void;
send(typeOrPayload: Record<string, unknown> | unknown[]): void;
// (undocumented)
state: 'initializing' | 'reconnecting' | 'connected';
// (undocumented)
@ -3000,6 +3105,9 @@ type SwUpdateRegistrationRequest = operations['sw___update-registration']['reque
// @public (undocumented)
type SwUpdateRegistrationResponse = operations['sw___update-registration']['responses']['200']['content']['application/json'];
// @public (undocumented)
type SystemWebhook = components['schemas']['SystemWebhook'];
// @public (undocumented)
type TestRequest = operations['test']['requestBody']['content']['application/json'];
@ -3197,7 +3305,9 @@ type UsersUpdateMemoRequest = operations['users___update-memo']['requestBody']['
// Warnings were encountered during analysis:
//
// src/entities.ts:25:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/entities.ts:35:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:220:4 - (ae-forgotten-export) The symbol "ReversiUpdateKey" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:230:4 - (ae-forgotten-export) The symbol "ReversiUpdateSettings" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package)

View file

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../../shared/.eslintrc.js',
],
};

View file

@ -0,0 +1,17 @@
import tsParser from '@typescript-eslint/parser';
import sharedConfig from '../../shared/eslint.config.js';
export default [
...sharedConfig,
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parserOptions: {
parser: tsParser,
project: ['./tsconfig.json'],
sourceType: 'module',
tsconfigRootDir: import.meta.dirname,
},
},
},
];

View file

@ -4,15 +4,13 @@
"description": "Misskey TypeGenerator",
"type": "module",
"scripts": {
"generate": "tsx src/generator.ts && eslint ./built/**/* --ext .ts --fix"
"generate": "tsx src/generator.ts && eslint ./built/**/*.ts --fix"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "^1.0.0",
"@readme/openapi-parser": "2.5.0",
"@types/node": "20.9.1",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"eslint": "8.53.0",
"openapi-types": "12.1.3",
"openapi-typescript": "6.7.3",
"ts-case-convert": "2.0.2",

View file

@ -20,7 +20,14 @@ async function generateBaseTypes(
}
lines.push('');
const generatedTypes = await openapiTS(openApiJsonPath, { exportType: true });
const generatedTypes = await openapiTS(openApiJsonPath, {
exportType: true,
transform(schemaObject) {
if ('format' in schemaObject && schemaObject.format === 'binary') {
return schemaObject.nullable ? 'Blob | null' : 'Blob';
}
},
});
lines.push(generatedTypes);
lines.push('');
@ -56,6 +63,8 @@ async function generateEndpoints(
endpointOutputPath: string,
) {
const endpoints: Endpoint[] = [];
const endpointReqMediaTypes: EndpointReqMediaType[] = [];
const endpointReqMediaTypesSet = new Set<string>();
// misskey-jsはPOST固定で送っているので、こちらも決め打ちする。別メソッドに対応することがあればこちらも直す必要あり
const paths = openApiDocs.paths ?? {};
@ -78,13 +87,24 @@ async function generateEndpoints(
const supportMediaTypes = Object.keys(reqContent);
if (supportMediaTypes.length > 0) {
// いまのところ複数のメディアタイプをとるエンドポイントは無いので決め打ちする
endpoint.request = new OperationTypeAlias(
const req = new OperationTypeAlias(
operationId,
path,
supportMediaTypes[0],
OperationsAliasType.REQUEST,
);
endpoint.request = req;
const reqType = new EndpointReqMediaType(path, req);
endpointReqMediaTypesSet.add(reqType.getMediaType());
endpointReqMediaTypes.push(reqType);
} else {
endpointReqMediaTypesSet.add('application/json');
endpointReqMediaTypes.push(new EndpointReqMediaType(path, undefined, 'application/json'));
}
} else {
endpointReqMediaTypesSet.add('application/json');
endpointReqMediaTypes.push(new EndpointReqMediaType(path, undefined, 'application/json'));
}
if (operation.responses && isResponseObject(operation.responses['200']) && operation.responses['200'].content) {
@ -137,6 +157,19 @@ async function generateEndpoints(
endpointOutputLine.push('}');
endpointOutputLine.push('');
function generateEndpointReqMediaTypesType() {
return `Record<keyof Endpoints, ${[...endpointReqMediaTypesSet].map((t) => `'${t}'`).join(' | ')}>`;
}
endpointOutputLine.push(`export const endpointReqTypes: ${generateEndpointReqMediaTypesType()} = {`);
endpointOutputLine.push(
...endpointReqMediaTypes.map(it => '\t' + it.toLine()),
);
endpointOutputLine.push('};');
endpointOutputLine.push('');
await writeFile(endpointOutputPath, endpointOutputLine.join('\n'));
}
@ -314,6 +347,26 @@ class Endpoint {
}
}
class EndpointReqMediaType {
public readonly path: string;
public readonly mediaType: string;
constructor(path: string, request: OperationTypeAlias, mediaType?: undefined);
constructor(path: string, request: undefined, mediaType: string);
constructor(path: string, request: OperationTypeAlias | undefined, mediaType?: string) {
this.path = path;
this.mediaType = mediaType ?? request?.mediaType ?? 'application/json';
}
getMediaType(): string {
return this.mediaType;
}
toLine(): string {
return `'${this.path}': '${this.mediaType}',`;
}
}
async function main() {
const generatePath = './built/autogen';
await mkdir(generatePath, { recursive: true });

View file

@ -1,7 +1,7 @@
{
"type": "module",
"name": "misskey-js",
"version": "2024.5.0",
"version": "2024.7.0",
"description": "Misskey SDK for JavaScript",
"license": "MIT",
"main": "./built/index.js",
@ -22,7 +22,7 @@
"tsd": "tsd",
"api": "pnpm api-extractor run --local --verbose",
"api-prod": "pnpm api-extractor run --verbose",
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
"eslint": "eslint './**/*.{js,jsx,ts,tsx}'",
"typecheck": "tsc --noEmit",
"lint": "pnpm typecheck && pnpm eslint",
"jest": "jest --coverage --detectOpenHandles",
@ -35,25 +35,23 @@
"directory": "packages/misskey-js"
},
"devDependencies": {
"@microsoft/api-extractor": "7.43.1",
"@misskey-dev/eslint-plugin": "1.0.0",
"@microsoft/api-extractor": "7.47.4",
"@swc/jest": "0.2.36",
"@types/jest": "29.5.12",
"@types/node": "20.12.7",
"@typescript-eslint/eslint-plugin": "7.7.1",
"@typescript-eslint/parser": "7.7.1",
"eslint": "8.57.0",
"@types/node": "20.14.12",
"@typescript-eslint/eslint-plugin": "7.17.0",
"@typescript-eslint/parser": "7.17.0",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
"mock-socket": "9.3.1",
"ncp": "2.0.0",
"nodemon": "3.1.0",
"execa": "8.0.1",
"tsd": "0.30.7",
"typescript": "5.4.5",
"esbuild": "0.19.11",
"glob": "10.3.12"
"nodemon": "3.1.4",
"execa": "9.3.0",
"tsd": "0.31.1",
"typescript": "5.5.4",
"esbuild": "0.23.0",
"glob": "11.0.0"
},
"files": [
"built"

View file

@ -3,7 +3,8 @@ export type Acct = {
host: string | null;
};
export function parse(acct: string): Acct {
export function parse(_acct: string): Acct {
let acct = _acct;
if (acct.startsWith('@')) acct = acct.substring(1);
const split = acct.split('@', 2);
return { username: split[0], host: split[1] || null };

View file

@ -1,7 +1,7 @@
import './autogen/apiClientJSDoc.js';
import { SwitchCaseResponseType } from './api.types.js';
import type { Endpoints } from './api.types.js';
import { endpointReqTypes } from './autogen/endpoint.js';
import type { SwitchCaseResponseType, Endpoints } from './api.types.js';
export type {
SwitchCaseResponseType,
@ -14,6 +14,7 @@ export type APIError = {
code: string;
message: string;
kind: 'client' | 'server';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
info: Record<string, any>;
};
@ -23,12 +24,13 @@ export function isAPIError(reason: Record<PropertyKey, unknown>): reason is APIE
export type FetchLike = (input: string, init?: {
method?: string;
body?: string;
body?: Blob | FormData | string;
credentials?: RequestCredentials;
cache?: RequestCache;
headers: { [key in string]: string }
}) => Promise<{
status: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
json(): Promise<any>;
}>;
@ -49,20 +51,56 @@ export class APIClient {
this.fetch = opts.fetch ?? ((...args) => fetch(...args));
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private assertIsRecord<T>(obj: T): obj is T & Record<string, any> {
return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
}
public request<E extends keyof Endpoints, P extends Endpoints[E]['req']>(
endpoint: E,
params: P = {} as P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>> {
return new Promise((resolve, reject) => {
this.fetch(`${this.origin}/api/${endpoint}`, {
method: 'POST',
body: JSON.stringify({
let mediaType = 'application/json';
if (endpoint in endpointReqTypes) {
mediaType = endpointReqTypes[endpoint];
}
let payload: FormData | string = '{}';
if (mediaType === 'application/json') {
payload = JSON.stringify({
...params,
i: credential !== undefined ? credential : this.credential,
}),
});
} else if (mediaType === 'multipart/form-data') {
payload = new FormData();
const i = credential !== undefined ? credential : this.credential;
if (i != null) {
payload.append('i', i);
}
if (this.assertIsRecord(params)) {
for (const key in params) {
const value = params[key];
if (value == null) continue;
if (value instanceof File || value instanceof Blob) {
payload.append(key, value);
} else if (typeof value === 'object') {
payload.append(key, JSON.stringify(value));
} else {
payload.append(key, value);
}
}
}
}
this.fetch(`${this.origin}/api/${endpoint}`, {
method: 'POST',
body: payload,
headers: {
'Content-Type': 'application/json',
'Content-Type': endpointReqTypes[endpoint],
},
credentials: 'omit',
cache: 'no-cache',

View file

@ -1,7 +1,8 @@
import { Endpoints as Gen } from './autogen/endpoint.js';
import { UserDetailed } from './autogen/models.js';
import { UsersShowRequest } from './autogen/entities.js';
import { AdminRolesCreateRequest, AdminRolesCreateResponse, UsersShowRequest } from './autogen/entities.js';
import {
PartialRolePolicyOverride,
SigninRequest,
SigninResponse,
SignupPendingRequest,
@ -27,11 +28,13 @@ type StrictExtract<Union, Cond> = Cond extends Union ? Union : never;
type IsCaseMatched<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
Endpoints[E]['res'] extends SwitchCase
// eslint-disable-next-line @typescript-eslint/no-explicit-any
? IsNeverType<StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>> extends false ? true : false
: false
type GetCaseResult<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
Endpoints[E]['res'] extends SwitchCase
// eslint-disable-next-line @typescript-eslint/no-explicit-any
? StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>[1]
: never
@ -79,5 +82,9 @@ export type Endpoints = Overwrite<
req: SigninRequest;
res: SigninResponse;
},
'admin/roles/create': {
req: Overwrite<AdminRolesCreateRequest, { policies: PartialRolePolicyOverride }>;
res: AdminRolesCreateResponse;
}
}
>

View file

@ -25,6 +25,66 @@ declare module '../api.js' {
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
request<E extends 'admin/abuse-report/notification-recipient/list', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
request<E extends 'admin/abuse-report/notification-recipient/show', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
request<E extends 'admin/abuse-report/notification-recipient/create', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
request<E extends 'admin/abuse-report/notification-recipient/update', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
request<E extends 'admin/abuse-report/notification-recipient/delete', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
@ -895,6 +955,66 @@ declare module '../api.js' {
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
request<E extends 'admin/system-webhook/create', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
request<E extends 'admin/system-webhook/delete', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
request<E extends 'admin/system-webhook/list', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
request<E extends 'admin/system-webhook/show', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
request<E extends 'admin/system-webhook/update', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*

View file

@ -4,6 +4,15 @@ import type {
AdminMetaResponse,
AdminAbuseUserReportsRequest,
AdminAbuseUserReportsResponse,
AdminAbuseReportNotificationRecipientListRequest,
AdminAbuseReportNotificationRecipientListResponse,
AdminAbuseReportNotificationRecipientShowRequest,
AdminAbuseReportNotificationRecipientShowResponse,
AdminAbuseReportNotificationRecipientCreateRequest,
AdminAbuseReportNotificationRecipientCreateResponse,
AdminAbuseReportNotificationRecipientUpdateRequest,
AdminAbuseReportNotificationRecipientUpdateResponse,
AdminAbuseReportNotificationRecipientDeleteRequest,
AdminAccountsCreateRequest,
AdminAccountsCreateResponse,
AdminAccountsDeleteRequest,
@ -104,6 +113,15 @@ import type {
AdminRolesUpdateDefaultPoliciesRequest,
AdminRolesUsersRequest,
AdminRolesUsersResponse,
AdminSystemWebhookCreateRequest,
AdminSystemWebhookCreateResponse,
AdminSystemWebhookDeleteRequest,
AdminSystemWebhookListRequest,
AdminSystemWebhookListResponse,
AdminSystemWebhookShowRequest,
AdminSystemWebhookShowResponse,
AdminSystemWebhookUpdateRequest,
AdminSystemWebhookUpdateResponse,
AnnouncementsRequest,
AnnouncementsResponse,
AnnouncementsShowRequest,
@ -573,6 +591,11 @@ import type {
export type Endpoints = {
'admin/meta': { req: EmptyRequest; res: AdminMetaResponse };
'admin/abuse-user-reports': { req: AdminAbuseUserReportsRequest; res: AdminAbuseUserReportsResponse };
'admin/abuse-report/notification-recipient/list': { req: AdminAbuseReportNotificationRecipientListRequest; res: AdminAbuseReportNotificationRecipientListResponse };
'admin/abuse-report/notification-recipient/show': { req: AdminAbuseReportNotificationRecipientShowRequest; res: AdminAbuseReportNotificationRecipientShowResponse };
'admin/abuse-report/notification-recipient/create': { req: AdminAbuseReportNotificationRecipientCreateRequest; res: AdminAbuseReportNotificationRecipientCreateResponse };
'admin/abuse-report/notification-recipient/update': { req: AdminAbuseReportNotificationRecipientUpdateRequest; res: AdminAbuseReportNotificationRecipientUpdateResponse };
'admin/abuse-report/notification-recipient/delete': { req: AdminAbuseReportNotificationRecipientDeleteRequest; res: EmptyResponse };
'admin/accounts/create': { req: AdminAccountsCreateRequest; res: AdminAccountsCreateResponse };
'admin/accounts/delete': { req: AdminAccountsDeleteRequest; res: EmptyResponse };
'admin/accounts/find-by-email': { req: AdminAccountsFindByEmailRequest; res: AdminAccountsFindByEmailResponse };
@ -652,6 +675,11 @@ export type Endpoints = {
'admin/roles/unassign': { req: AdminRolesUnassignRequest; res: EmptyResponse };
'admin/roles/update-default-policies': { req: AdminRolesUpdateDefaultPoliciesRequest; res: EmptyResponse };
'admin/roles/users': { req: AdminRolesUsersRequest; res: AdminRolesUsersResponse };
'admin/system-webhook/create': { req: AdminSystemWebhookCreateRequest; res: AdminSystemWebhookCreateResponse };
'admin/system-webhook/delete': { req: AdminSystemWebhookDeleteRequest; res: EmptyResponse };
'admin/system-webhook/list': { req: AdminSystemWebhookListRequest; res: AdminSystemWebhookListResponse };
'admin/system-webhook/show': { req: AdminSystemWebhookShowRequest; res: AdminSystemWebhookShowResponse };
'admin/system-webhook/update': { req: AdminSystemWebhookUpdateRequest; res: AdminSystemWebhookUpdateResponse };
'announcements': { req: AnnouncementsRequest; res: AnnouncementsResponse };
'announcements/show': { req: AnnouncementsShowRequest; res: AnnouncementsShowResponse };
'antennas/create': { req: AntennasCreateRequest; res: AntennasCreateResponse };
@ -954,3 +982,385 @@ export type Endpoints = {
'reversi/surrender': { req: ReversiSurrenderRequest; res: EmptyResponse };
'reversi/verify': { req: ReversiVerifyRequest; res: ReversiVerifyResponse };
}
export const endpointReqTypes: Record<keyof Endpoints, 'application/json' | 'multipart/form-data'> = {
'admin/meta': 'application/json',
'admin/abuse-user-reports': 'application/json',
'admin/abuse-report/notification-recipient/list': 'application/json',
'admin/abuse-report/notification-recipient/show': 'application/json',
'admin/abuse-report/notification-recipient/create': 'application/json',
'admin/abuse-report/notification-recipient/update': 'application/json',
'admin/abuse-report/notification-recipient/delete': 'application/json',
'admin/accounts/create': 'application/json',
'admin/accounts/delete': 'application/json',
'admin/accounts/find-by-email': 'application/json',
'admin/ad/create': 'application/json',
'admin/ad/delete': 'application/json',
'admin/ad/list': 'application/json',
'admin/ad/update': 'application/json',
'admin/announcements/create': 'application/json',
'admin/announcements/delete': 'application/json',
'admin/announcements/list': 'application/json',
'admin/announcements/update': 'application/json',
'admin/avatar-decorations/create': 'application/json',
'admin/avatar-decorations/delete': 'application/json',
'admin/avatar-decorations/list': 'application/json',
'admin/avatar-decorations/update': 'application/json',
'admin/delete-all-files-of-a-user': 'application/json',
'admin/unset-user-avatar': 'application/json',
'admin/unset-user-banner': 'application/json',
'admin/drive/clean-remote-files': 'application/json',
'admin/drive/cleanup': 'application/json',
'admin/drive/files': 'application/json',
'admin/drive/show-file': 'application/json',
'admin/emoji/add-aliases-bulk': 'application/json',
'admin/emoji/add': 'application/json',
'admin/emoji/copy': 'application/json',
'admin/emoji/delete-bulk': 'application/json',
'admin/emoji/delete': 'application/json',
'admin/emoji/import-zip': 'application/json',
'admin/emoji/list-remote': 'application/json',
'admin/emoji/list': 'application/json',
'admin/emoji/remove-aliases-bulk': 'application/json',
'admin/emoji/set-aliases-bulk': 'application/json',
'admin/emoji/set-category-bulk': 'application/json',
'admin/emoji/set-license-bulk': 'application/json',
'admin/emoji/update': 'application/json',
'admin/federation/delete-all-files': 'application/json',
'admin/federation/refresh-remote-instance-metadata': 'application/json',
'admin/federation/remove-all-following': 'application/json',
'admin/federation/update-instance': 'application/json',
'admin/get-index-stats': 'application/json',
'admin/get-table-stats': 'application/json',
'admin/get-user-ips': 'application/json',
'admin/invite/create': 'application/json',
'admin/invite/list': 'application/json',
'admin/promo/create': 'application/json',
'admin/queue/clear': 'application/json',
'admin/queue/deliver-delayed': 'application/json',
'admin/queue/inbox-delayed': 'application/json',
'admin/queue/promote': 'application/json',
'admin/queue/stats': 'application/json',
'admin/relays/add': 'application/json',
'admin/relays/list': 'application/json',
'admin/relays/remove': 'application/json',
'admin/reset-password': 'application/json',
'admin/resolve-abuse-user-report': 'application/json',
'admin/send-email': 'application/json',
'admin/server-info': 'application/json',
'admin/show-moderation-logs': 'application/json',
'admin/show-user': 'application/json',
'admin/show-users': 'application/json',
'admin/suspend-user': 'application/json',
'admin/unsuspend-user': 'application/json',
'admin/update-meta': 'application/json',
'admin/delete-account': 'application/json',
'admin/update-user-note': 'application/json',
'admin/roles/create': 'application/json',
'admin/roles/delete': 'application/json',
'admin/roles/list': 'application/json',
'admin/roles/show': 'application/json',
'admin/roles/update': 'application/json',
'admin/roles/assign': 'application/json',
'admin/roles/unassign': 'application/json',
'admin/roles/update-default-policies': 'application/json',
'admin/roles/users': 'application/json',
'admin/system-webhook/create': 'application/json',
'admin/system-webhook/delete': 'application/json',
'admin/system-webhook/list': 'application/json',
'admin/system-webhook/show': 'application/json',
'admin/system-webhook/update': 'application/json',
'announcements': 'application/json',
'announcements/show': 'application/json',
'antennas/create': 'application/json',
'antennas/delete': 'application/json',
'antennas/list': 'application/json',
'antennas/notes': 'application/json',
'antennas/show': 'application/json',
'antennas/update': 'application/json',
'ap/get': 'application/json',
'ap/show': 'application/json',
'app/create': 'application/json',
'app/show': 'application/json',
'auth/accept': 'application/json',
'auth/session/generate': 'application/json',
'auth/session/show': 'application/json',
'auth/session/userkey': 'application/json',
'blocking/create': 'application/json',
'blocking/delete': 'application/json',
'blocking/list': 'application/json',
'channels/create': 'application/json',
'channels/featured': 'application/json',
'channels/follow': 'application/json',
'channels/followed': 'application/json',
'channels/owned': 'application/json',
'channels/show': 'application/json',
'channels/timeline': 'application/json',
'channels/unfollow': 'application/json',
'channels/update': 'application/json',
'channels/favorite': 'application/json',
'channels/unfavorite': 'application/json',
'channels/my-favorites': 'application/json',
'channels/search': 'application/json',
'charts/active-users': 'application/json',
'charts/ap-request': 'application/json',
'charts/drive': 'application/json',
'charts/federation': 'application/json',
'charts/instance': 'application/json',
'charts/notes': 'application/json',
'charts/user/drive': 'application/json',
'charts/user/following': 'application/json',
'charts/user/notes': 'application/json',
'charts/user/pv': 'application/json',
'charts/user/reactions': 'application/json',
'charts/users': 'application/json',
'clips/add-note': 'application/json',
'clips/remove-note': 'application/json',
'clips/create': 'application/json',
'clips/delete': 'application/json',
'clips/list': 'application/json',
'clips/notes': 'application/json',
'clips/show': 'application/json',
'clips/update': 'application/json',
'clips/favorite': 'application/json',
'clips/unfavorite': 'application/json',
'clips/my-favorites': 'application/json',
'drive': 'application/json',
'drive/files': 'application/json',
'drive/files/attached-notes': 'application/json',
'drive/files/check-existence': 'application/json',
'drive/files/create': 'multipart/form-data',
'drive/files/delete': 'application/json',
'drive/files/find-by-hash': 'application/json',
'drive/files/find': 'application/json',
'drive/files/show': 'application/json',
'drive/files/update': 'application/json',
'drive/files/upload-from-url': 'application/json',
'drive/folders': 'application/json',
'drive/folders/create': 'application/json',
'drive/folders/delete': 'application/json',
'drive/folders/find': 'application/json',
'drive/folders/show': 'application/json',
'drive/folders/update': 'application/json',
'drive/stream': 'application/json',
'email-address/available': 'application/json',
'endpoint': 'application/json',
'endpoints': 'application/json',
'export-custom-emojis': 'application/json',
'federation/followers': 'application/json',
'federation/following': 'application/json',
'federation/instances': 'application/json',
'federation/show-instance': 'application/json',
'federation/update-remote-user': 'application/json',
'federation/users': 'application/json',
'federation/stats': 'application/json',
'following/create': 'application/json',
'following/delete': 'application/json',
'following/update': 'application/json',
'following/update-all': 'application/json',
'following/invalidate': 'application/json',
'following/requests/accept': 'application/json',
'following/requests/cancel': 'application/json',
'following/requests/list': 'application/json',
'following/requests/reject': 'application/json',
'gallery/featured': 'application/json',
'gallery/popular': 'application/json',
'gallery/posts': 'application/json',
'gallery/posts/create': 'application/json',
'gallery/posts/delete': 'application/json',
'gallery/posts/like': 'application/json',
'gallery/posts/show': 'application/json',
'gallery/posts/unlike': 'application/json',
'gallery/posts/update': 'application/json',
'get-online-users-count': 'application/json',
'get-avatar-decorations': 'application/json',
'hashtags/list': 'application/json',
'hashtags/search': 'application/json',
'hashtags/show': 'application/json',
'hashtags/trend': 'application/json',
'hashtags/users': 'application/json',
'i': 'application/json',
'i/2fa/done': 'application/json',
'i/2fa/key-done': 'application/json',
'i/2fa/password-less': 'application/json',
'i/2fa/register-key': 'application/json',
'i/2fa/register': 'application/json',
'i/2fa/update-key': 'application/json',
'i/2fa/remove-key': 'application/json',
'i/2fa/unregister': 'application/json',
'i/apps': 'application/json',
'i/authorized-apps': 'application/json',
'i/claim-achievement': 'application/json',
'i/change-password': 'application/json',
'i/delete-account': 'application/json',
'i/export-blocking': 'application/json',
'i/export-following': 'application/json',
'i/export-mute': 'application/json',
'i/export-notes': 'application/json',
'i/export-clips': 'application/json',
'i/export-favorites': 'application/json',
'i/export-user-lists': 'application/json',
'i/export-antennas': 'application/json',
'i/favorites': 'application/json',
'i/gallery/likes': 'application/json',
'i/gallery/posts': 'application/json',
'i/import-blocking': 'application/json',
'i/import-following': 'application/json',
'i/import-muting': 'application/json',
'i/import-user-lists': 'application/json',
'i/import-antennas': 'application/json',
'i/notifications': 'application/json',
'i/notifications-grouped': 'application/json',
'i/page-likes': 'application/json',
'i/pages': 'application/json',
'i/pin': 'application/json',
'i/read-all-unread-notes': 'application/json',
'i/read-announcement': 'application/json',
'i/regenerate-token': 'application/json',
'i/registry/get-all': 'application/json',
'i/registry/get-detail': 'application/json',
'i/registry/get': 'application/json',
'i/registry/keys-with-type': 'application/json',
'i/registry/keys': 'application/json',
'i/registry/remove': 'application/json',
'i/registry/scopes-with-domain': 'application/json',
'i/registry/set': 'application/json',
'i/revoke-token': 'application/json',
'i/signin-history': 'application/json',
'i/unpin': 'application/json',
'i/update-email': 'application/json',
'i/update': 'application/json',
'i/move': 'application/json',
'i/webhooks/create': 'application/json',
'i/webhooks/list': 'application/json',
'i/webhooks/show': 'application/json',
'i/webhooks/update': 'application/json',
'i/webhooks/delete': 'application/json',
'invite/create': 'application/json',
'invite/delete': 'application/json',
'invite/list': 'application/json',
'invite/limit': 'application/json',
'meta': 'application/json',
'emojis': 'application/json',
'emoji': 'application/json',
'miauth/gen-token': 'application/json',
'mute/create': 'application/json',
'mute/delete': 'application/json',
'mute/list': 'application/json',
'renote-mute/create': 'application/json',
'renote-mute/delete': 'application/json',
'renote-mute/list': 'application/json',
'my/apps': 'application/json',
'notes': 'application/json',
'notes/children': 'application/json',
'notes/clips': 'application/json',
'notes/conversation': 'application/json',
'notes/create': 'application/json',
'notes/delete': 'application/json',
'notes/favorites/create': 'application/json',
'notes/favorites/delete': 'application/json',
'notes/featured': 'application/json',
'notes/global-timeline': 'application/json',
'notes/hybrid-timeline': 'application/json',
'notes/local-timeline': 'application/json',
'notes/mentions': 'application/json',
'notes/polls/recommendation': 'application/json',
'notes/polls/vote': 'application/json',
'notes/reactions': 'application/json',
'notes/reactions/create': 'application/json',
'notes/reactions/delete': 'application/json',
'notes/renotes': 'application/json',
'notes/replies': 'application/json',
'notes/search-by-tag': 'application/json',
'notes/search': 'application/json',
'notes/show': 'application/json',
'notes/state': 'application/json',
'notes/thread-muting/create': 'application/json',
'notes/thread-muting/delete': 'application/json',
'notes/timeline': 'application/json',
'notes/translate': 'application/json',
'notes/unrenote': 'application/json',
'notes/user-list-timeline': 'application/json',
'notifications/create': 'application/json',
'notifications/flush': 'application/json',
'notifications/mark-all-as-read': 'application/json',
'notifications/test-notification': 'application/json',
'page-push': 'application/json',
'pages/create': 'application/json',
'pages/delete': 'application/json',
'pages/featured': 'application/json',
'pages/like': 'application/json',
'pages/show': 'application/json',
'pages/unlike': 'application/json',
'pages/update': 'application/json',
'flash/create': 'application/json',
'flash/delete': 'application/json',
'flash/featured': 'application/json',
'flash/like': 'application/json',
'flash/show': 'application/json',
'flash/unlike': 'application/json',
'flash/update': 'application/json',
'flash/my': 'application/json',
'flash/my-likes': 'application/json',
'ping': 'application/json',
'pinned-users': 'application/json',
'promo/read': 'application/json',
'roles/list': 'application/json',
'roles/show': 'application/json',
'roles/users': 'application/json',
'roles/notes': 'application/json',
'request-reset-password': 'application/json',
'reset-db': 'application/json',
'reset-password': 'application/json',
'server-info': 'application/json',
'stats': 'application/json',
'sw/show-registration': 'application/json',
'sw/update-registration': 'application/json',
'sw/register': 'application/json',
'sw/unregister': 'application/json',
'test': 'application/json',
'username/available': 'application/json',
'users': 'application/json',
'users/clips': 'application/json',
'users/followers': 'application/json',
'users/following': 'application/json',
'users/gallery/posts': 'application/json',
'users/get-frequently-replied-users': 'application/json',
'users/featured-notes': 'application/json',
'users/lists/create': 'application/json',
'users/lists/delete': 'application/json',
'users/lists/list': 'application/json',
'users/lists/pull': 'application/json',
'users/lists/push': 'application/json',
'users/lists/show': 'application/json',
'users/lists/favorite': 'application/json',
'users/lists/unfavorite': 'application/json',
'users/lists/update': 'application/json',
'users/lists/create-from-public': 'application/json',
'users/lists/update-membership': 'application/json',
'users/lists/get-memberships': 'application/json',
'users/notes': 'application/json',
'users/pages': 'application/json',
'users/flashs': 'application/json',
'users/reactions': 'application/json',
'users/recommendation': 'application/json',
'users/relation': 'application/json',
'users/report-abuse': 'application/json',
'users/search-by-username-and-host': 'application/json',
'users/search': 'application/json',
'users/show': 'application/json',
'users/achievements': 'application/json',
'users/update-memo': 'application/json',
'fetch-rss': 'application/json',
'fetch-external-resources': 'application/json',
'retention': 'application/json',
'bubble-game/register': 'application/json',
'bubble-game/ranking': 'application/json',
'reversi/cancel-match': 'application/json',
'reversi/games': 'application/json',
'reversi/match': 'application/json',
'reversi/invitations': 'application/json',
'reversi/show-game': 'application/json',
'reversi/surrender': 'application/json',
'reversi/verify': 'application/json',
};

View file

@ -7,6 +7,15 @@ export type EmptyResponse = Record<string, unknown> | undefined;
export type AdminMetaResponse = operations['admin___meta']['responses']['200']['content']['application/json'];
export type AdminAbuseUserReportsRequest = operations['admin___abuse-user-reports']['requestBody']['content']['application/json'];
export type AdminAbuseUserReportsResponse = operations['admin___abuse-user-reports']['responses']['200']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientListRequest = operations['admin___abuse-report___notification-recipient___list']['requestBody']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientListResponse = operations['admin___abuse-report___notification-recipient___list']['responses']['200']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientShowRequest = operations['admin___abuse-report___notification-recipient___show']['requestBody']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientShowResponse = operations['admin___abuse-report___notification-recipient___show']['responses']['200']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientCreateRequest = operations['admin___abuse-report___notification-recipient___create']['requestBody']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientCreateResponse = operations['admin___abuse-report___notification-recipient___create']['responses']['200']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientUpdateRequest = operations['admin___abuse-report___notification-recipient___update']['requestBody']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientUpdateResponse = operations['admin___abuse-report___notification-recipient___update']['responses']['200']['content']['application/json'];
export type AdminAbuseReportNotificationRecipientDeleteRequest = operations['admin___abuse-report___notification-recipient___delete']['requestBody']['content']['application/json'];
export type AdminAccountsCreateRequest = operations['admin___accounts___create']['requestBody']['content']['application/json'];
export type AdminAccountsCreateResponse = operations['admin___accounts___create']['responses']['200']['content']['application/json'];
export type AdminAccountsDeleteRequest = operations['admin___accounts___delete']['requestBody']['content']['application/json'];
@ -107,6 +116,15 @@ export type AdminRolesUnassignRequest = operations['admin___roles___unassign']['
export type AdminRolesUpdateDefaultPoliciesRequest = operations['admin___roles___update-default-policies']['requestBody']['content']['application/json'];
export type AdminRolesUsersRequest = operations['admin___roles___users']['requestBody']['content']['application/json'];
export type AdminRolesUsersResponse = operations['admin___roles___users']['responses']['200']['content']['application/json'];
export type AdminSystemWebhookCreateRequest = operations['admin___system-webhook___create']['requestBody']['content']['application/json'];
export type AdminSystemWebhookCreateResponse = operations['admin___system-webhook___create']['responses']['200']['content']['application/json'];
export type AdminSystemWebhookDeleteRequest = operations['admin___system-webhook___delete']['requestBody']['content']['application/json'];
export type AdminSystemWebhookListRequest = operations['admin___system-webhook___list']['requestBody']['content']['application/json'];
export type AdminSystemWebhookListResponse = operations['admin___system-webhook___list']['responses']['200']['content']['application/json'];
export type AdminSystemWebhookShowRequest = operations['admin___system-webhook___show']['requestBody']['content']['application/json'];
export type AdminSystemWebhookShowResponse = operations['admin___system-webhook___show']['responses']['200']['content']['application/json'];
export type AdminSystemWebhookUpdateRequest = operations['admin___system-webhook___update']['requestBody']['content']['application/json'];
export type AdminSystemWebhookUpdateResponse = operations['admin___system-webhook___update']['responses']['200']['content']['application/json'];
export type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json'];
export type AnnouncementsResponse = operations['announcements']['responses']['200']['content']['application/json'];
export type AnnouncementsShowRequest = operations['announcements___show']['requestBody']['content']['application/json'];

View file

@ -51,3 +51,5 @@ export type ReversiGameDetailed = components['schemas']['ReversiGameDetailed'];
export type MetaLite = components['schemas']['MetaLite'];
export type MetaDetailedOnly = components['schemas']['MetaDetailedOnly'];
export type MetaDetailed = components['schemas']['MetaDetailed'];
export type SystemWebhook = components['schemas']['SystemWebhook'];
export type AbuseReportNotificationRecipient = components['schemas']['AbuseReportNotificationRecipient'];

View file

@ -30,6 +30,56 @@ export type paths = {
*/
post: operations['admin___abuse-user-reports'];
};
'/admin/abuse-report/notification-recipient/list': {
/**
* admin/abuse-report/notification-recipient/list
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
post: operations['admin___abuse-report___notification-recipient___list'];
};
'/admin/abuse-report/notification-recipient/show': {
/**
* admin/abuse-report/notification-recipient/show
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
post: operations['admin___abuse-report___notification-recipient___show'];
};
'/admin/abuse-report/notification-recipient/create': {
/**
* admin/abuse-report/notification-recipient/create
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
post: operations['admin___abuse-report___notification-recipient___create'];
};
'/admin/abuse-report/notification-recipient/update': {
/**
* admin/abuse-report/notification-recipient/update
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
post: operations['admin___abuse-report___notification-recipient___update'];
};
'/admin/abuse-report/notification-recipient/delete': {
/**
* admin/abuse-report/notification-recipient/delete
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
post: operations['admin___abuse-report___notification-recipient___delete'];
};
'/admin/accounts/create': {
/**
* admin/accounts/create
@ -742,6 +792,56 @@ export type paths = {
*/
post: operations['admin___roles___users'];
};
'/admin/system-webhook/create': {
/**
* admin/system-webhook/create
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
post: operations['admin___system-webhook___create'];
};
'/admin/system-webhook/delete': {
/**
* admin/system-webhook/delete
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
post: operations['admin___system-webhook___delete'];
};
'/admin/system-webhook/list': {
/**
* admin/system-webhook/list
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
post: operations['admin___system-webhook___list'];
};
'/admin/system-webhook/show': {
/**
* admin/system-webhook/show
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
post: operations['admin___system-webhook___show'];
};
'/admin/system-webhook/update': {
/**
* admin/system-webhook/update
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
post: operations['admin___system-webhook___update'];
};
'/announcements': {
/**
* announcements
@ -4121,7 +4221,8 @@ export type components = {
userId: string | null;
}) | null;
localOnly?: boolean;
reactionAcceptance: string | null;
/** @enum {string|null} */
reactionAcceptance: 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote' | null;
reactionEmojis: {
[key: string]: string;
};
@ -4342,7 +4443,7 @@ export type components = {
id: string;
/** Format: date-time */
createdAt: string;
/** @example lenna.jpg */
/** @example 192.jpg */
name: string;
/** @example image/jpeg */
type: string;
@ -4641,6 +4742,7 @@ export type components = {
maintainerName: string | null;
maintainerEmail: string | null;
isSilenced: boolean;
isMediaSilenced: boolean;
/** Format: url */
iconUrl: string | null;
/** Format: url */
@ -4831,6 +4933,7 @@ export type components = {
canHideAds: boolean;
driveCapacityMb: number;
alwaysMarkNsfw: boolean;
canUpdateBioMedia: boolean;
pinLimit: number;
antennaLimit: number;
wordMuteLimit: number;
@ -4986,6 +5089,11 @@ export type components = {
serverRules: string[];
themeColor: string | null;
policies: components['schemas']['RolePolicies'];
/**
* @default local
* @enum {string}
*/
noteSearchableScope: 'local' | 'global';
};
MetaDetailedOnly: {
features?: {
@ -5008,6 +5116,32 @@ export type components = {
cacheRemoteSensitiveFiles: boolean;
};
MetaDetailed: components['schemas']['MetaLite'] & components['schemas']['MetaDetailedOnly'];
SystemWebhook: {
id: string;
isActive: boolean;
/** Format: date-time */
updatedAt: string;
/** Format: date-time */
latestSentAt: string | null;
latestStatus: number | null;
name: string;
on: ('abuseReport' | 'abuseReportResolved' | 'userCreated')[];
url: string;
secret: string;
};
AbuseReportNotificationRecipient: {
id: string;
isActive: boolean;
/** Format: date-time */
updatedAt: string;
name: string;
/** @enum {string} */
method: 'email' | 'webhook';
userId?: string;
user?: components['schemas']['UserLite'];
systemWebhookId?: string;
systemWebhook?: components['schemas']['SystemWebhook'];
};
};
responses: never;
parameters: never;
@ -5061,6 +5195,7 @@ export type operations = {
enableServiceWorker: boolean;
translatorAvailable: boolean;
silencedHosts?: string[];
mediaSilencedHosts: string[];
pinnedUsers: string[];
hiddenTags: string[];
blockedHosts: string[];
@ -5281,6 +5416,292 @@ export type operations = {
};
};
};
/**
* admin/abuse-report/notification-recipient/list
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
'admin___abuse-report___notification-recipient___list': {
requestBody: {
content: {
'application/json': {
method?: ('email' | 'webhook')[];
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['AbuseReportNotificationRecipient'][];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/abuse-report/notification-recipient/show
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient*
*/
'admin___abuse-report___notification-recipient___show': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['AbuseReportNotificationRecipient'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/abuse-report/notification-recipient/create
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
'admin___abuse-report___notification-recipient___create': {
requestBody: {
content: {
'application/json': {
isActive: boolean;
name: string;
/** @enum {string} */
method: 'email' | 'webhook';
/** Format: misskey:id */
userId?: string;
/** Format: misskey:id */
systemWebhookId?: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['AbuseReportNotificationRecipient'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/abuse-report/notification-recipient/update
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
'admin___abuse-report___notification-recipient___update': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
isActive: boolean;
name: string;
/** @enum {string} */
method: 'email' | 'webhook';
/** Format: misskey:id */
userId?: string;
/** Format: misskey:id */
systemWebhookId?: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['AbuseReportNotificationRecipient'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/abuse-report/notification-recipient/delete
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient*
*/
'admin___abuse-report___notification-recipient___delete': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
};
};
};
responses: {
/** @description OK (without any results) */
204: {
content: never;
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/accounts/create
* @description No description provided.
@ -5625,15 +6046,15 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
id: string;
memo: string;
url: string;
imageUrl: string;
place: string;
priority: string;
ratio: number;
expiresAt: number;
startsAt: number;
dayOfWeek: number;
memo?: string;
url?: string;
imageUrl?: string;
place?: string;
priority?: string;
ratio?: number;
expiresAt?: number;
startsAt?: number;
dayOfWeek?: number;
};
};
};
@ -5833,6 +6254,11 @@ export type operations = {
untilId?: string;
/** Format: misskey:id */
userId?: string | null;
/**
* @default active
* @enum {string}
*/
status?: 'all' | 'active' | 'archived';
};
};
};
@ -6543,7 +6969,7 @@ export type operations = {
* @example 15eca7fba0480996e2245f5185bf39f2
*/
md5: string;
/** @example lenna.jpg */
/** @example 192.jpg */
name: string;
/** @example image/jpeg */
type: string;
@ -9374,6 +9800,7 @@ export type operations = {
perUserListTimelineCacheMax?: number;
notesPerOneAd?: number;
silencedHosts?: string[] | null;
mediaSilencedHosts?: string[] | null;
/** @description [Deprecated] Use "urlPreviewSummaryProxyUrl" instead. */
summalyProxy?: string | null;
urlPreviewEnabled?: boolean;
@ -9759,21 +10186,21 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
roleId: string;
name: string;
description: string;
color: string | null;
iconUrl: string | null;
name?: string;
description?: string;
color?: string | null;
iconUrl?: string | null;
/** @enum {string} */
target: 'manual' | 'conditional';
condFormula: Record<string, never>;
isPublic: boolean;
isModerator: boolean;
isAdministrator: boolean;
target?: 'manual' | 'conditional';
condFormula?: Record<string, never>;
isPublic?: boolean;
isModerator?: boolean;
isAdministrator?: boolean;
isExplorable?: boolean;
asBadge: boolean;
canEditMembersByModerator: boolean;
displayOrder: number;
policies: Record<string, never>;
asBadge?: boolean;
canEditMembersByModerator?: boolean;
displayOrder?: number;
policies?: Record<string, never>;
};
};
};
@ -10042,6 +10469,287 @@ export type operations = {
};
};
};
/**
* admin/system-webhook/create
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
'admin___system-webhook___create': {
requestBody: {
content: {
'application/json': {
isActive: boolean;
name: string;
on: ('abuseReport' | 'abuseReportResolved' | 'userCreated')[];
url: string;
secret: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['SystemWebhook'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/system-webhook/delete
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
'admin___system-webhook___delete': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
};
};
};
responses: {
/** @description OK (without any results) */
204: {
content: never;
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/system-webhook/list
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
'admin___system-webhook___list': {
requestBody: {
content: {
'application/json': {
isActive?: boolean;
on?: ('abuseReport' | 'abuseReportResolved' | 'userCreated')[];
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['SystemWebhook'][];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/system-webhook/show
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
'admin___system-webhook___show': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['SystemWebhook'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* admin/system-webhook/update
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook*
*/
'admin___system-webhook___update': {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
id: string;
isActive: boolean;
name: string;
on: ('abuseReport' | 'abuseReportResolved' | 'userCreated')[];
url: string;
secret: string;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': components['schemas']['SystemWebhook'];
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* announcements
* @description No description provided.
@ -13141,7 +13849,7 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
clipId: string;
name: string;
name?: string;
isPublic?: boolean;
description?: string | null;
};
@ -13591,7 +14299,7 @@ export type operations = {
* Format: binary
* @description The file contents.
*/
file: string;
file: Blob;
};
};
};
@ -15990,9 +16698,9 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
postId: string;
title: string;
title?: string;
description?: string | null;
fileIds: string[];
fileIds?: string[];
/** @default false */
isSensitive?: boolean;
};
@ -19942,12 +20650,11 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
webhookId: string;
name: string;
url: string;
/** @default */
secret?: string;
on: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction' | 'edited')[];
active: boolean;
name?: string;
url?: string;
secret?: string | null;
on?: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction' | 'edited')[];
active?: boolean;
};
};
};
@ -23604,16 +24311,16 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
pageId: string;
title: string;
name: string;
title?: string;
name?: string;
summary?: string | null;
content: {
content?: {
[key: string]: unknown;
}[];
variables: {
variables?: {
[key: string]: unknown;
}[];
script: string;
script?: string;
/** Format: misskey:id */
eyeCatchingImageId?: string | null;
/** @enum {string} */
@ -27781,4 +28488,3 @@ export type operations = {
};
};
};

View file

@ -1,3 +1,13 @@
import type { operations } from './autogen/types.js';
import type {
AbuseReportNotificationRecipient, Ad,
Announcement,
EmojiDetailed, InviteCode,
MetaDetailed,
Note,
Role, SystemWebhook, UserLite,
} from './autogen/models.js';
export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned', 'edited'] as const;
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;
@ -139,12 +149,38 @@ export const moderationLogTypes = [
'deleteAvatarDecoration',
'unsetUserAvatar',
'unsetUserBanner',
'createSystemWebhook',
'updateSystemWebhook',
'deleteSystemWebhook',
'createAbuseReportNotificationRecipient',
'updateAbuseReportNotificationRecipient',
'deleteAbuseReportNotificationRecipient',
] as const;
// See: packages/backend/src/core/ReversiService.ts@L410
export const reversiUpdateKeys = [
'map',
'bw',
'isLlotheo',
'canPutEverywhere',
'loopedBoard',
'timeLimitForEachTurn',
] as const;
export type ReversiUpdateKey = typeof reversiUpdateKeys[number];
type AvatarDecoration = UserLite['avatarDecorations'][number];
type ReceivedAbuseReport = {
reportId: AbuseReportNotificationRecipient['id'];
report: operations['admin___abuse-user-reports']['responses'][200]['content']['application/json'];
forwarded: boolean;
};
export type ModerationLogPayloads = {
updateServerSettings: {
before: any | null;
after: any | null;
before: MetaDetailed | null;
after: MetaDetailed | null;
};
suspend: {
userId: string;
@ -170,16 +206,16 @@ export type ModerationLogPayloads = {
};
addCustomEmoji: {
emojiId: string;
emoji: any;
emoji: EmojiDetailed;
};
updateCustomEmoji: {
emojiId: string;
before: any;
after: any;
before: EmojiDetailed;
after: EmojiDetailed;
};
deleteCustomEmoji: {
emojiId: string;
emoji: any;
emoji: EmojiDetailed;
};
assignRole: {
userId: string;
@ -198,16 +234,16 @@ export type ModerationLogPayloads = {
};
createRole: {
roleId: string;
role: any;
role: Role;
};
updateRole: {
roleId: string;
before: any;
after: any;
before: Role;
after: Role;
};
deleteRole: {
roleId: string;
role: any;
role: Role;
};
clearQueue: Record<string, never>;
promoteQueue: Record<string, never>;
@ -222,39 +258,39 @@ export type ModerationLogPayloads = {
noteUserId: string;
noteUserUsername: string;
noteUserHost: string | null;
note: any;
note: Note;
};
createGlobalAnnouncement: {
announcementId: string;
announcement: any;
announcement: Announcement;
};
createUserAnnouncement: {
announcementId: string;
announcement: any;
announcement: Announcement;
userId: string;
userUsername: string;
userHost: string | null;
};
updateGlobalAnnouncement: {
announcementId: string;
before: any;
after: any;
before: Announcement;
after: Announcement;
};
updateUserAnnouncement: {
announcementId: string;
before: any;
after: any;
before: Announcement;
after: Announcement;
userId: string;
userUsername: string;
userHost: string | null;
};
deleteGlobalAnnouncement: {
announcementId: string;
announcement: any;
announcement: Announcement;
};
deleteUserAnnouncement: {
announcementId: string;
announcement: any;
announcement: Announcement;
userId: string;
userUsername: string;
userHost: string | null;
@ -292,37 +328,37 @@ export type ModerationLogPayloads = {
};
resolveAbuseReport: {
reportId: string;
report: any;
report: ReceivedAbuseReport;
forwarded: boolean;
};
createInvitation: {
invitations: any[];
invitations: InviteCode[];
};
createAd: {
adId: string;
ad: any;
ad: Ad;
};
updateAd: {
adId: string;
before: any;
after: any;
before: Ad;
after: Ad;
};
deleteAd: {
adId: string;
ad: any;
ad: Ad;
};
createAvatarDecoration: {
avatarDecorationId: string;
avatarDecoration: any;
avatarDecoration: AvatarDecoration;
};
updateAvatarDecoration: {
avatarDecorationId: string;
before: any;
after: any;
before: AvatarDecoration;
after: AvatarDecoration;
};
deleteAvatarDecoration: {
avatarDecorationId: string;
avatarDecoration: any;
avatarDecoration: AvatarDecoration;
};
unsetUserAvatar: {
userId: string;
@ -336,4 +372,30 @@ export type ModerationLogPayloads = {
userHost: string | null;
fileId: string;
};
createSystemWebhook: {
systemWebhookId: string;
webhook: SystemWebhook;
};
updateSystemWebhook: {
systemWebhookId: string;
before: SystemWebhook;
after: SystemWebhook;
};
deleteSystemWebhook: {
systemWebhookId: string;
webhook: SystemWebhook;
};
createAbuseReportNotificationRecipient: {
recipientId: string;
recipient: AbuseReportNotificationRecipient;
};
updateAbuseReportNotificationRecipient: {
recipientId: string;
before: AbuseReportNotificationRecipient;
after: AbuseReportNotificationRecipient;
};
deleteAbuseReportNotificationRecipient: {
recipientId: string;
recipient: AbuseReportNotificationRecipient;
};
};

View file

@ -1,5 +1,14 @@
import { ModerationLogPayloads } from './consts.js';
import { Announcement, EmojiDetailed, MeDetailed, Page, User, UserDetailedNotMe } from './autogen/models.js';
import {
Announcement,
EmojiDetailed,
MeDetailed,
Page,
Role,
RolePolicies,
User,
UserDetailedNotMe,
} from './autogen/models.js';
export * from './autogen/entities.js';
export * from './autogen/models.js';
@ -10,6 +19,7 @@ export type DateString = string;
export type PageEvent = {
pageId: Page['id'];
event: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var: any;
userId: User['id'];
user: User;
@ -135,8 +145,23 @@ export type ModerationLog = {
type: 'unsetUserAvatar';
info: ModerationLogPayloads['unsetUserAvatar'];
} | {
type: 'unsetUserBanner';
info: ModerationLogPayloads['unsetUserBanner'];
type: 'createSystemWebhook';
info: ModerationLogPayloads['createSystemWebhook'];
} | {
type: 'updateSystemWebhook';
info: ModerationLogPayloads['updateSystemWebhook'];
} | {
type: 'deleteSystemWebhook';
info: ModerationLogPayloads['deleteSystemWebhook'];
} | {
type: 'createAbuseReportNotificationRecipient';
info: ModerationLogPayloads['createAbuseReportNotificationRecipient'];
} | {
type: 'updateAbuseReportNotificationRecipient';
info: ModerationLogPayloads['updateAbuseReportNotificationRecipient'];
} | {
type: 'deleteAbuseReportNotificationRecipient';
info: ModerationLogPayloads['deleteAbuseReportNotificationRecipient'];
});
export type ServerStats = {
@ -224,3 +249,7 @@ export type SigninResponse = {
id: User['id'],
i: string,
};
type Values<T extends Record<PropertyKey, unknown>> = T[keyof T];
export type PartialRolePolicyOverride = Partial<{[k in keyof RolePolicies]: Omit<Values<Role['policies']>, 'value'> & { value: RolePolicies[k] }}>;

View file

@ -15,7 +15,7 @@ export function urlQuery(obj: Record<string, string | number | boolean | undefin
.join('&');
}
type AnyOf<T extends Record<any, any>> = T[keyof T];
type AnyOf<T extends Record<PropertyKey, unknown>> = T[keyof T];
type StreamEvents = {
_connected_: void;
@ -25,6 +25,7 @@ type StreamEvents = {
/**
* Misskey stream connection
*/
// eslint-disable-next-line import/no-default-export
export default class Stream extends EventEmitter<StreamEvents> {
private stream: _ReconnectingWebsocket.default;
public state: 'initializing' | 'reconnecting' | 'connected' = 'initializing';
@ -34,7 +35,7 @@ export default class Stream extends EventEmitter<StreamEvents> {
private idCounter = 0;
constructor(origin: string, user: { token: string; } | null, options?: {
WebSocket?: any;
WebSocket?: WebSocket;
}) {
super();
@ -51,6 +52,7 @@ export default class Stream extends EventEmitter<StreamEvents> {
this.send = this.send.bind(this);
this.close = this.close.bind(this);
// eslint-disable-next-line no-param-reassign
options = options ?? { };
const query = urlQuery({
@ -91,8 +93,8 @@ export default class Stream extends EventEmitter<StreamEvents> {
this.sharedConnectionPools.push(pool);
}
const connection = new SharedConnection(this, channel, pool, name);
this.sharedConnections.push(connection);
const connection = new SharedConnection<Channels[C]>(this, channel, pool, name);
this.sharedConnections.push(connection as unknown as SharedConnection);
return connection;
}
@ -106,7 +108,7 @@ export default class Stream extends EventEmitter<StreamEvents> {
private connectToChannel<C extends keyof Channels>(channel: C, params: Channels[C]['params']): NonSharedConnection<Channels[C]> {
const connection = new NonSharedConnection(this, channel, this.genId(), params);
this.nonSharedConnections.push(connection);
this.nonSharedConnections.push(connection as unknown as NonSharedConnection);
return connection;
}
@ -174,9 +176,9 @@ export default class Stream extends EventEmitter<StreamEvents> {
* ! JSONで行われます !
*/
public send(typeOrPayload: string): void
public send(typeOrPayload: string, payload: any): void
public send(typeOrPayload: Record<string, any> | any[]): void
public send(typeOrPayload: string | Record<string, any> | any[], payload?: any): void {
public send(typeOrPayload: string, payload: unknown): void
public send(typeOrPayload: Record<string, unknown> | unknown[]): void
public send(typeOrPayload: string | Record<string, unknown> | unknown[], payload?: unknown): void {
if (typeof typeOrPayload === 'string') {
this.stream.send(JSON.stringify({
type: typeOrPayload,
@ -211,7 +213,7 @@ class Pool {
public id: string;
protected stream: Stream;
public users = 0;
private disposeTimerId: any;
private disposeTimerId: ReturnType<typeof setTimeout> | null = null;
private isConnected = false;
constructor(stream: Stream, channel: string, id: string) {
@ -275,7 +277,7 @@ class Pool {
}
}
export abstract class Connection<Channel extends AnyOf<Channels> = any> extends EventEmitter<Channel['events']> {
export abstract class Connection<Channel extends AnyOf<Channels> = AnyOf<Channels>> extends EventEmitter<Channel['events']> {
public channel: string;
protected stream: Stream;
public abstract id: string;
@ -291,7 +293,9 @@ export abstract class Connection<Channel extends AnyOf<Channels> = any> extends
this.stream = stream;
this.channel = channel;
this.name = name;
if (name !== undefined) {
this.name = name;
}
}
public send<T extends keyof Channel['receives']>(type: T, body: Channel['receives'][T]): void {
@ -307,7 +311,7 @@ export abstract class Connection<Channel extends AnyOf<Channels> = any> extends
public abstract dispose(): void;
}
class SharedConnection<Channel extends AnyOf<Channels> = any> extends Connection<Channel> {
class SharedConnection<Channel extends AnyOf<Channels> = AnyOf<Channels>> extends Connection<Channel> {
private pool: Pool;
public get id(): string {
@ -326,11 +330,11 @@ class SharedConnection<Channel extends AnyOf<Channels> = any> extends Connection
public dispose(): void {
this.pool.dec();
this.removeAllListeners();
this.stream.removeSharedConnection(this);
this.stream.removeSharedConnection(this as unknown as SharedConnection);
}
}
class NonSharedConnection<Channel extends AnyOf<Channels> = any> extends Connection<Channel> {
class NonSharedConnection<Channel extends AnyOf<Channels> = AnyOf<Channels>> extends Connection<Channel> {
public id: string;
protected params: Channel['params'];
@ -357,6 +361,6 @@ class NonSharedConnection<Channel extends AnyOf<Channels> = any> extends Connect
public dispose(): void {
this.removeAllListeners();
this.stream.send('disconnect', { id: this.id });
this.stream.disconnectToChannel(this);
this.stream.disconnectToChannel(this as unknown as NonSharedConnection);
}
}

View file

@ -21,6 +21,14 @@ import {
ServerStatsLog,
ReversiGameDetailed,
} from './entities.js';
import {
ReversiUpdateKey,
} from './consts.js';
type ReversiUpdateSettings<K extends ReversiUpdateKey> = {
key: K;
value: ReversiGameDetailed[K];
};
export type Channels = {
main: {
@ -51,6 +59,7 @@ export type Channels = {
registryUpdated: (payload: {
scope?: string[];
key: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any | null;
}) => void;
driveFileCreated: (payload: DriveFile) => void;
@ -224,8 +233,8 @@ export type Channels = {
ended: (payload: { winnerId: User['id'] | null; game: ReversiGameDetailed; }) => void;
canceled: (payload: { userId: User['id']; }) => void;
changeReadyStates: (payload: { user1: boolean; user2: boolean; }) => void;
updateSettings: (payload: { userId: User['id']; key: string; value: any; }) => void;
log: (payload: Record<string, any>) => void;
updateSettings: <K extends ReversiUpdateKey>(payload: { userId: User['id']; key: K; value: ReversiGameDetailed[K]; }) => void;
log: (payload: Record<string, unknown>) => void;
};
receives: {
putStone: {
@ -234,10 +243,7 @@ export type Channels = {
};
ready: boolean;
cancel: null | Record<string, never>;
updateSettings: {
key: string;
value: any;
};
updateSettings: ReversiUpdateSettings<ReversiUpdateKey>;
claimTimeIsUp: null | Record<string, never>;
}
}

View file

@ -5,13 +5,19 @@ enableFetchMocks();
function getFetchCall(call: any[]) {
const { body, method } = call[1];
if (body != null && typeof body != 'string') {
const contentType = call[1].headers['Content-Type'];
if (
body == null ||
(contentType === 'application/json' && typeof body !== 'string') ||
(contentType === 'multipart/form-data' && !(body instanceof FormData))
) {
throw new Error('invalid body');
}
return {
url: call[0],
method: method,
body: JSON.parse(body as any)
contentType: contentType,
body: body instanceof FormData ? Object.fromEntries(body.entries()) : JSON.parse(body),
};
}
@ -45,6 +51,7 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/i',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN' }
});
});
@ -78,10 +85,52 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/notes/show',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN', noteId: 'aaaaa' }
});
});
test('multipart/form-data', async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
if (req.method == 'POST' && req.url == 'https://misskey.test/api/drive/files/create') {
if (req.headers.get('Content-Type')?.includes('multipart/form-data')) {
return JSON.stringify({ id: 'foo' });
} else {
return { status: 400 };
}
} else {
return { status: 404 };
}
});
const cli = new APIClient({
origin: 'https://misskey.test',
credential: 'TOKEN',
});
const testFile = new File([], 'foo.txt');
const res = await cli.request('drive/files/create', {
file: testFile,
name: null, // nullのパラメータは消える
});
expect(res).toEqual({
id: 'foo'
});
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/drive/files/create',
method: 'POST',
contentType: 'multipart/form-data',
body: {
i: 'TOKEN',
file: testFile,
}
});
});
test('204 No Content で null が返る', async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
@ -104,6 +153,7 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/reset-password',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN', token: 'aaa', password: 'aaa' }
});
});
@ -209,4 +259,42 @@ describe('API', () => {
expect(isAPIError(e)).toEqual(false);
}
});
test('admin/roles/create の型が合う', async() => {
fetchMock.resetMocks();
fetchMock.mockResponse(async () => {
return {
// 本来返すべき値は`Role`型だが、テストなのでお茶を濁す
status: 200,
body: '{}'
};
});
const cli = new APIClient({
origin: 'https://misskey.test',
credential: 'TOKEN',
});
await cli.request('admin/roles/create', {
name: 'aaa',
asBadge: false,
canEditMembersByModerator: false,
color: '#123456',
condFormula: {},
description: '',
displayOrder: 0,
iconUrl: '',
isAdministrator: false,
isExplorable: false,
isModerator: false,
isPublic: false,
policies: {
ltlAvailable: {
value: true,
priority: 0,
useDefault: false,
},
},
target: 'manual',
});
})
});

View file

@ -15,6 +15,7 @@
"experimentalDecorators": true,
"noImplicitReturns": true,
"esModuleInterop": true,
"exactOptionalPropertyTypes": true,
"typeRoots": [
"./node_modules/@types"
],