Skip to content

Commit

Permalink
バックエンドが生成するapi.jsonからmisskey-jsの型を作成する (#12434)
Browse files Browse the repository at this point in the history
* ひとまず生成できるところまで

* ファイル構成整理

* 生成コマンド整理

* 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 <[email protected]>
Co-authored-by: syuilo <[email protected]>
  • Loading branch information
3 people authored Dec 2, 2023
1 parent 92029ac commit 3364162
Show file tree
Hide file tree
Showing 42 changed files with 27,097 additions and 4,008 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"build-assets": "node ./scripts/build-assets.mjs",
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
"build-storybook": "pnpm --filter frontend build-storybook",
"build-misskey-js-with-types": "pnpm --filter backend build && pnpm --filter backend generate-api-json && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build",
"start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js",
"start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js",
"init": "pnpm migrate",
Expand Down Expand Up @@ -57,7 +58,8 @@
"cross-env": "7.0.3",
"cypress": "13.6.0",
"eslint": "8.54.0",
"start-server-and-test": "2.0.3"
"start-server-and-test": "2.0.3",
"ncp": "2.0.0"
},
"optionalDependencies": {
"@tensorflow/tfjs-core": "4.4.0"
Expand Down
76 changes: 76 additions & 0 deletions packages/backend/src/server/api/endpoints/admin/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,82 @@ export const meta = {
type: 'number',
optional: false, nullable: false,
},
backgroundImageUrl: {
type: 'string',
optional: false, nullable: true,
},
deeplAuthKey: {
type: 'string',
optional: false, nullable: true,
},
deeplIsPro: {
type: 'boolean',
optional: false, nullable: false,
},
defaultDarkTheme: {
type: 'string',
optional: false, nullable: true,
},
defaultLightTheme: {
type: 'string',
optional: false, nullable: true,
},
description: {
type: 'string',
optional: false, nullable: true,
},
disableRegistration: {
type: 'boolean',
optional: false, nullable: false,
},
impressumUrl: {
type: 'string',
optional: false, nullable: true,
},
maintainerEmail: {
type: 'string',
optional: false, nullable: true,
},
maintainerName: {
type: 'string',
optional: false, nullable: true,
},
name: {
type: 'string',
optional: false, nullable: true,
},
objectStorageS3ForcePathStyle: {
type: 'boolean',
optional: false, nullable: false,
},
privacyPolicyUrl: {
type: 'string',
optional: false, nullable: true,
},
repositoryUrl: {
type: 'string',
optional: false, nullable: false,
},
summalyProxy: {
type: 'string',
optional: false, nullable: true,
},
themeColor: {
type: 'string',
optional: false, nullable: true,
},
tosUrl: {
type: 'string',
optional: false, nullable: true,
},
uri: {
type: 'string',
optional: false, nullable: false,
},
version: {
type: 'string',
optional: false, nullable: false,
},
},
},
} as const;
Expand Down
29 changes: 24 additions & 5 deletions packages/backend/src/server/api/endpoints/federation/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,32 @@ export const paramDef = {
blocked: { type: 'boolean', nullable: true },
notResponding: { type: 'boolean', nullable: true },
suspended: { type: 'boolean', nullable: true },
silenced: { type: "boolean", nullable: true },
silenced: { type: 'boolean', nullable: true },
federating: { type: 'boolean', nullable: true },
subscribing: { type: 'boolean', nullable: true },
publishing: { type: 'boolean', nullable: true },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 },
offset: { type: 'integer', default: 0 },
sort: { type: 'string' },
sort: {
type: 'string',
nullable: true,
enum: [
'+pubSub',
'-pubSub',
'+notes',
'-notes',
'+users',
'-users',
'+following',
'-following',
'+followers',
'-followers',
'+firstRetrievedAt',
'-firstRetrievedAt',
'+latestRequestReceivedAt',
'-latestRequestReceivedAt',
],
},
},
required: [],
} as const;
Expand Down Expand Up @@ -103,18 +122,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
}

if (typeof ps.silenced === "boolean") {
if (typeof ps.silenced === 'boolean') {
const meta = await this.metaService.fetch(true);

if (ps.silenced) {
if (meta.silencedHosts.length === 0) {
return [];
}
query.andWhere("instance.host IN (:...silences)", {
query.andWhere('instance.host IN (:...silences)', {
silences: meta.silencedHosts,
});
} else if (meta.silencedHosts.length > 0) {
query.andWhere("instance.host NOT IN (:...silences)", {
query.andWhere('instance.host NOT IN (:...silences)', {
silences: meta.silencedHosts,
});
}
Expand Down
27 changes: 27 additions & 0 deletions packages/backend/src/server/api/endpoints/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,33 @@ export const meta = {
},
},
},
backgroundImageUrl: {
type: 'string',
optional: false, nullable: true,
},
impressumUrl: {
type: 'string',
optional: false, nullable: true,
},
logoImageUrl: {
type: 'string',
optional: false, nullable: true,
},
privacyPolicyUrl: {
type: 'string',
optional: false, nullable: true,
},
serverRules: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
},
},
themeColor: {
type: 'string',
optional: false, nullable: true,
},
},
},
} as const;
Expand Down
8 changes: 4 additions & 4 deletions packages/frontend/src/components/MkEmojiPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)));
}

Expand All @@ -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}:`;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkFeaturedPhotos.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/components/MkInstanceCardMini.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkInviteCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}>();

Expand Down
7 changes: 3 additions & 4 deletions packages/frontend/src/components/MkVisitorDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});

Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/custom-emojis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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);
});

Expand Down
1 change: 0 additions & 1 deletion packages/frontend/src/filters/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
});

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/_error_.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/about.emojis.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/auth.form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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<{
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/auth.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Loading

0 comments on commit 3364162

Please sign in to comment.