バックエンドが生成するapi.jsonからmisskey-jsの型を作成する (#12434)
* ひとまず生成できるところまで * ファイル構成整理 * 生成コマンド整理 * misskey-jsへの組み込み * fix generator.ts * wip * fix generator.ts * fix package.json * 生成ロジックの調整 * 型レベルでのswitch-case機構をmisskey-jsからfrontendに持ち込めるようにした * 型チェック用のtsconfig.jsonを作成 * 他のエンドポイントを呼ぶ関数にも適用 * 未使用エンティティなどを削除 * misskey-js側で手動定義されていた型を自動生成された型に移行(ただしapi.jsonがvalidでなくなってしまったので後で修正する) * messagingは廃止されている(テストのビルドエラー解消) * validなapi.jsonを出力できるように修正 * 修正漏れ対応 * Ajvに怒られて起動できなかったところを修正 * fix ci(途中) * パラメータenumをやめる * add command * add api.json * 都度自動生成をやめる * 一気通貫スクリプト修正 * fix ci * 生成ロジック修正 * フロントの型チェックは結局やらなかったので戻しておく * fix pnpm-lock.yaml * add README.md --------- Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com> Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
@@ -149,7 +149,7 @@ const size = computed(() => props.asReactionPicker ? reactionPickerSize.value :
|
||||
const width = computed(() => props.asReactionPicker ? reactionPickerWidth.value : 3);
|
||||
const height = computed(() => props.asReactionPicker ? reactionPickerHeight.value : 2);
|
||||
const q = ref<string>('');
|
||||
const searchResultCustom = ref<Misskey.entities.CustomEmoji[]>([]);
|
||||
const searchResultCustom = ref<Misskey.entities.EmojiSimple[]>([]);
|
||||
const searchResultUnicode = ref<UnicodeEmojiDef[]>([]);
|
||||
const tab = ref<'index' | 'custom' | 'unicode' | 'tags'>('index');
|
||||
|
||||
@@ -196,7 +196,7 @@ watch(q, () => {
|
||||
const searchCustom = () => {
|
||||
const max = 100;
|
||||
const emojis = customEmojis.value;
|
||||
const matches = new Set<Misskey.entities.CustomEmoji>();
|
||||
const matches = new Set<Misskey.entities.EmojiSimple>();
|
||||
|
||||
const exactMatch = emojis.find(emoji => emoji.name === newQ);
|
||||
if (exactMatch) matches.add(exactMatch);
|
||||
@@ -326,7 +326,7 @@ watch(q, () => {
|
||||
searchResultUnicode.value = Array.from(searchUnicode());
|
||||
});
|
||||
|
||||
function filterAvailable(emoji: Misskey.entities.CustomEmoji): boolean {
|
||||
function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean {
|
||||
return (emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.includes(r.id)));
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ function reset() {
|
||||
q.value = '';
|
||||
}
|
||||
|
||||
function getKey(emoji: string | Misskey.entities.CustomEmoji | UnicodeEmojiDef): string {
|
||||
function getKey(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef): string {
|
||||
return typeof emoji === 'string' ? emoji : 'char' in emoji ? emoji.char : `:${emoji.name}:`;
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@ import { ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
const meta = ref<Misskey.entities.DetailedInstanceMetadata>();
|
||||
const meta = ref<Misskey.entities.MetaResponse>();
|
||||
|
||||
os.api('meta', { detail: true }).then(gotMeta => {
|
||||
meta.value = gotMeta;
|
||||
|
@@ -21,15 +21,15 @@ import * as os from '@/os.js';
|
||||
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
||||
|
||||
const props = defineProps<{
|
||||
instance: Misskey.entities.Instance;
|
||||
instance: Misskey.entities.FederationInstance;
|
||||
}>();
|
||||
|
||||
let chartValues = $ref<number[] | null>(null);
|
||||
|
||||
os.apiGet('charts/instance', { host: props.instance.host, limit: 16 + 1, span: 'day' }).then(res => {
|
||||
// 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く
|
||||
res.requests.received.splice(0, 1);
|
||||
chartValues = res.requests.received;
|
||||
res['requests.received'].splice(0, 1);
|
||||
chartValues = res['requests.received'];
|
||||
});
|
||||
|
||||
function getInstanceIcon(instance): string {
|
||||
|
@@ -67,7 +67,7 @@ import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
const props = defineProps<{
|
||||
invite: Misskey.entities.Invite;
|
||||
invite: Misskey.entities.InviteCode;
|
||||
moderator?: boolean;
|
||||
}>();
|
||||
|
||||
|
@@ -67,15 +67,14 @@ import number from '@/filters/number.js';
|
||||
import MkNumber from '@/components/MkNumber.vue';
|
||||
import XActiveUsersChart from '@/components/MkVisitorDashboard.ActiveUsersChart.vue';
|
||||
|
||||
let meta = $ref<Misskey.entities.Instance>();
|
||||
let stats = $ref(null);
|
||||
let meta = $ref<Misskey.entities.MetaResponse | null>(null);
|
||||
let stats = $ref<Misskey.entities.StatsResponse | null>(null);
|
||||
|
||||
os.api('meta', { detail: true }).then(_meta => {
|
||||
meta = _meta;
|
||||
});
|
||||
|
||||
os.api('stats', {
|
||||
}).then((res) => {
|
||||
os.api('stats', {}).then((res) => {
|
||||
stats = res;
|
||||
});
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import { useStream } from '@/stream.js';
|
||||
import { get, set } from '@/scripts/idb-proxy.js';
|
||||
|
||||
const storageCache = await get('emojis');
|
||||
export const customEmojis = shallowRef<Misskey.entities.CustomEmoji[]>(Array.isArray(storageCache) ? storageCache : []);
|
||||
export const customEmojis = shallowRef<Misskey.entities.EmojiSimple[]>(Array.isArray(storageCache) ? storageCache : []);
|
||||
export const customEmojiCategories = computed<[ ...string[], null ]>(() => {
|
||||
const categories = new Set<string>();
|
||||
for (const emoji of customEmojis.value) {
|
||||
@@ -21,7 +21,7 @@ export const customEmojiCategories = computed<[ ...string[], null ]>(() => {
|
||||
return markRaw([...Array.from(categories), null]);
|
||||
});
|
||||
|
||||
export const customEmojisMap = new Map<string, Misskey.entities.CustomEmoji>();
|
||||
export const customEmojisMap = new Map<string, Misskey.entities.EmojiSimple>();
|
||||
watch(customEmojis, emojis => {
|
||||
customEmojisMap.clear();
|
||||
for (const emoji of emojis) {
|
||||
@@ -38,7 +38,7 @@ stream.on('emojiAdded', emojiData => {
|
||||
});
|
||||
|
||||
stream.on('emojiUpdated', emojiData => {
|
||||
customEmojis.value = customEmojis.value.map(item => emojiData.emojis.find(search => search.name === item.name) as Misskey.entities.CustomEmoji ?? item);
|
||||
customEmojis.value = customEmojis.value.map(item => emojiData.emojis.find(search => search.name === item.name) as Misskey.entities.EmojiSimple ?? item);
|
||||
set('emojis', customEmojis.value);
|
||||
});
|
||||
|
||||
|
@@ -3,7 +3,6 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Misskey from 'misskey-js';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { url } from '@/config.js';
|
||||
|
||||
|
@@ -15,7 +15,7 @@ const cached = miLocalStorage.getItem('instance');
|
||||
|
||||
// TODO: instanceをリアクティブにするかは再考の余地あり
|
||||
|
||||
export const instance: Misskey.entities.InstanceMetadata = reactive(cached ? JSON.parse(cached) : {
|
||||
export const instance: Misskey.entities.MetaResponse = reactive(cached ? JSON.parse(cached) : {
|
||||
// TODO: set default values
|
||||
});
|
||||
|
||||
|
@@ -44,7 +44,7 @@ const props = withDefaults(defineProps<{
|
||||
|
||||
let loaded = $ref(false);
|
||||
let serverIsDead = $ref(false);
|
||||
let meta = $ref<Misskey.entities.LiteInstanceMetadata | null>(null);
|
||||
let meta = $ref<Misskey.entities.MetaResponse | null>(null);
|
||||
|
||||
os.api('meta', {
|
||||
detail: false,
|
||||
|
@@ -48,7 +48,7 @@ import { $i } from '@/account.js';
|
||||
|
||||
const customEmojiTags = getCustomEmojiTags();
|
||||
let q = $ref('');
|
||||
let searchEmojis = $ref<Misskey.entities.CustomEmoji[]>(null);
|
||||
let searchEmojis = $ref<Misskey.entities.EmojiSimple[]>(null);
|
||||
let selectedTags = $ref(new Set());
|
||||
|
||||
function search() {
|
||||
|
@@ -27,7 +27,7 @@ import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const props = defineProps<{
|
||||
session: Misskey.entities.AuthSession;
|
||||
session: Misskey.entities.AuthSessionShowResponse;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@@ -56,7 +56,7 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
let state = $ref<'waiting' | 'accepted' | 'fetch-session-error' | 'denied' | null>(null);
|
||||
let session = $ref<Misskey.entities.AuthSession | null>(null);
|
||||
let session = $ref<Misskey.entities.AuthSessionShowResponse | null>(null);
|
||||
|
||||
function accepted() {
|
||||
state = 'accepted';
|
||||
|
@@ -144,8 +144,8 @@ const props = defineProps<{
|
||||
|
||||
let tab = $ref('overview');
|
||||
let chartSrc = $ref('instance-requests');
|
||||
let meta = $ref<Misskey.entities.AdminInstanceMetadata | null>(null);
|
||||
let instance = $ref<Misskey.entities.Instance | null>(null);
|
||||
let meta = $ref<Misskey.entities.AdminMetaResponse | null>(null);
|
||||
let instance = $ref<Misskey.entities.FederationInstance | null>(null);
|
||||
let suspended = $ref(false);
|
||||
let isBlocked = $ref(false);
|
||||
let isSilenced = $ref(false);
|
||||
@@ -169,10 +169,10 @@ async function fetch(): Promise<void> {
|
||||
instance = await os.api('federation/show-instance', {
|
||||
host: props.host,
|
||||
});
|
||||
suspended = instance.isSuspended;
|
||||
isBlocked = instance.isBlocked;
|
||||
isSilenced = instance.isSilenced;
|
||||
faviconUrl = getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.iconUrl, 'preview');
|
||||
suspended = instance?.isSuspended ?? false;
|
||||
isBlocked = instance?.isBlocked ?? false;
|
||||
isSilenced = instance?.isSilenced ?? false;
|
||||
faviconUrl = getProxiedImageUrlNullable(instance?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance?.iconUrl, 'preview');
|
||||
}
|
||||
|
||||
async function toggleBlock(): Promise<void> {
|
||||
@@ -188,8 +188,9 @@ async function toggleSilenced(): Promise<void> {
|
||||
if (!meta) throw new Error('No meta?');
|
||||
if (!instance) throw new Error('No instance?');
|
||||
const { host } = instance;
|
||||
const silencedHosts = meta.silencedHosts ?? [];
|
||||
await os.api('admin/update-meta', {
|
||||
silencedHosts: isSilenced ? meta.silencedHosts.concat([host]) : meta.silencedHosts.filter(x => x !== host),
|
||||
silencedHosts: isSilenced ? silencedHosts.concat([host]) : silencedHosts.filter(x => x !== host),
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkPagination ref="pagingComponent" :pagination="pagination">
|
||||
<template #default="{ items }">
|
||||
<div class="_gaps_s">
|
||||
<MkInviteCode v-for="item in (items as Misskey.entities.Invite[])" :key="item.id" :invite="item" :onDeleted="deleted"/>
|
||||
<MkInviteCode v-for="item in (items as Misskey.entities.InviteCode[])" :key="item.id" :invite="item" :onDeleted="deleted"/>
|
||||
</div>
|
||||
</template>
|
||||
</MkPagination>
|
||||
|
@@ -48,11 +48,15 @@ import MkNumber from '@/components/MkNumber.vue';
|
||||
import MkVisitorDashboard from '@/components/MkVisitorDashboard.vue';
|
||||
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
||||
|
||||
let meta = $ref<Misskey.entities.Instance>();
|
||||
let instances = $ref<any[]>();
|
||||
let meta = $ref<Misskey.entities.MetaResponse>();
|
||||
let instances = $ref<Misskey.entities.FederationInstance[]>();
|
||||
|
||||
function getInstanceIcon(instance): string {
|
||||
return getProxiedImageUrl(instance.iconUrl, 'preview');
|
||||
function getInstanceIcon(instance: Misskey.entities.FederationInstance): string {
|
||||
if (!instance.iconUrl) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return getProxiedImageUrl(instance.iconUrl, 'preview');
|
||||
}
|
||||
|
||||
os.api('meta', { detail: true }).then(_meta => {
|
||||
|
@@ -10,7 +10,12 @@ import { $i } from '@/account.js';
|
||||
export const pendingApiRequestsCount = ref(0);
|
||||
|
||||
// Implements Misskey.api.ApiClient.request
|
||||
export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Misskey.Endpoints[E]['res']> {
|
||||
export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
|
||||
endpoint: E,
|
||||
data: P = {} as any,
|
||||
token?: string | null | undefined,
|
||||
signal?: AbortSignal,
|
||||
): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
|
||||
if (endpoint.includes('://')) throw new Error('invalid endpoint');
|
||||
pendingApiRequestsCount.value++;
|
||||
|
||||
@@ -51,7 +56,12 @@ export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoin
|
||||
return promise;
|
||||
}
|
||||
|
||||
export function apiExternal<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(hostUrl: string, endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Misskey.Endpoints[E]['res']> {
|
||||
export function apiExternal<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
|
||||
hostUrl: string,
|
||||
endpoint: E, data: P = {} as any,
|
||||
token?: string | null | undefined,
|
||||
signal?: AbortSignal,
|
||||
): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
|
||||
if (!/^https?:\/\//.test(hostUrl)) throw new Error('invalid host name');
|
||||
if (endpoint.includes('://')) throw new Error('invalid endpoint');
|
||||
pendingApiRequestsCount.value++;
|
||||
@@ -95,7 +105,10 @@ export function apiExternal<E extends keyof Misskey.Endpoints, P extends Misskey
|
||||
}
|
||||
|
||||
// Implements Misskey.api.ApiClient.request
|
||||
export function apiGet <E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(endpoint: E, data: P = {} as any): Promise<Misskey.Endpoints[E]['res']> {
|
||||
export function apiGet<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
|
||||
endpoint: E,
|
||||
data: P = {} as any,
|
||||
): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
|
||||
pendingApiRequestsCount.value++;
|
||||
|
||||
const onFinally = () => {
|
||||
|
@@ -47,7 +47,7 @@ const props = defineProps<{
|
||||
refreshIntervalSec?: number;
|
||||
}>();
|
||||
|
||||
const instances = ref<Misskey.entities.Instance[]>([]);
|
||||
const instances = ref<Misskey.entities.FederationInstance[]>([]);
|
||||
const fetching = ref(true);
|
||||
let key = $ref(0);
|
||||
|
||||
|
Reference in New Issue
Block a user