diff --git a/package.json b/package.json index 6bcb0bd460..ce679a8bcb 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ }, "devDependencies": { "@misskey-dev/eslint-plugin": "2.1.0", + "@types/js-yaml": "4.0.9", "@types/node": "22.17.2", "@typescript-eslint/eslint-plugin": "8.40.0", "@typescript-eslint/parser": "8.40.0", diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index 91ef41eedf..9cd8ac474c 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -127,7 +127,7 @@ export function galleryPost(isSensitive = false) { } } -export function file(isSensitive = false) { +export function file(isSensitive = false): entities.DriveFile { return { id: 'somefileid', createdAt: '2016-12-28T22:49:51.000Z', diff --git a/packages/frontend/src/aiscript/api.ts b/packages/frontend/src/aiscript/api.ts index a876e94ee8..0549ab76a0 100644 --- a/packages/frontend/src/aiscript/api.ts +++ b/packages/frontend/src/aiscript/api.ts @@ -86,7 +86,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string }) throw new errors.AiScriptRuntimeError('expected param'); } utils.assertObject(param); - return misskeyApi(ep.value, utils.valToJs(param) as object, actualToken).then(res => { + return misskeyApi(ep.value as keyof Misskey.Endpoints, utils.valToJs(param) as object, actualToken).then(res => { return utils.jsToVal(res); }, err => { return values.ERROR('request_failed', utils.jsToVal(err)); diff --git a/packages/frontend/src/components/MkAuthConfirm.vue b/packages/frontend/src/components/MkAuthConfirm.vue index b3331d742b..8744b50926 100644 --- a/packages/frontend/src/components/MkAuthConfirm.vue +++ b/packages/frontend/src/components/MkAuthConfirm.vue @@ -167,9 +167,13 @@ async function init() { for (const user of usersRes) { if (users.value.has(user.id)) continue; + const account = accounts.find(a => a.id === user.id); + + if (!account || account.token == null) continue; + users.value.set(user.id, { ...user, - token: accounts.find(a => a.id === user.id)!.token, + token: account.token, }); } } diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue index e5b9533cd7..cf5d95e11b 100644 --- a/packages/frontend/src/components/MkAutocomplete.vue +++ b/packages/frontend/src/components/MkAutocomplete.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + ({{ emoji.aliasOf }}) @@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
    -
  1. +
  2. {{ param }}
@@ -194,6 +194,11 @@ const mfmParams = ref([]); const select = ref(-1); const zIndex = os.claimZIndex('high'); +function completeMfmParam(param: string) { + if (props.type !== 'mfmParam') throw new Error('Invalid type'); + complete('mfmParam', props.q.params.toSpliced(-1, 1, param).join(',')); +} + function complete(type: T, value: CompleteInfo[T]['payload']) { emit('done', { type, value }); emit('closed'); diff --git a/packages/frontend/src/components/MkCropperDialog.stories.impl.ts b/packages/frontend/src/components/MkCropperDialog.stories.impl.ts index bd6733f9a8..7ac3e2a2cd 100644 --- a/packages/frontend/src/components/MkCropperDialog.stories.impl.ts +++ b/packages/frontend/src/components/MkCropperDialog.stories.impl.ts @@ -38,7 +38,7 @@ export const Default = { }; }, args: { - file: file(), + imageFile: file(), aspectRatio: NaN, }, parameters: { diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue index 9f1364aec4..19c98c3738 100644 --- a/packages/frontend/src/components/MkDrive.vue +++ b/packages/frontend/src/components/MkDrive.vue @@ -699,7 +699,7 @@ useGlobalEvent('driveFoldersDeleted', (folders) => { } }); -let connection: Misskey.ChannelConnection | null = null; +let connection: Misskey.IChannelConnection | null = null; onMounted(() => { if (store.s.realtimeMode) { diff --git a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue index d18fe0ed0c..17823deb85 100644 --- a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue +++ b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue @@ -160,7 +160,7 @@ const embedPreviewUrl = computed(() => { const isEmbedWithScrollbar = computed(() => embedRouteWithScrollbar.includes(props.entity)); const header = ref(props.params?.header ?? true); -const maxHeight = ref(props.params?.maxHeight !== 0 ? props.params?.maxHeight ?? undefined : 500); +const maxHeight = ref(props.params?.maxHeight !== 0 ? props.params?.maxHeight ?? null : 500); const colorMode = ref<'light' | 'dark' | 'auto'>(props.params?.colorMode ?? 'auto'); const rounded = ref(props.params?.rounded ?? true); diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue index 6ac4441cac..8d697499a5 100644 --- a/packages/frontend/src/components/MkFormDialog.vue +++ b/packages/frontend/src/components/MkFormDialog.vue @@ -41,11 +41,11 @@ SPDX-License-Identifier: AGPL-3.0-only - + - + @@ -77,7 +77,7 @@ import MkRange from './MkRange.vue'; import MkButton from './MkButton.vue'; import MkRadios from './MkRadios.vue'; import XFile from './MkFormDialog.file.vue'; -import type { Form } from '@/utility/form.js'; +import type { EnumItem, Form, RadioFormItem } from '@/utility/form.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; import { i18n } from '@/i18n.js'; @@ -99,7 +99,11 @@ const dialog = useTemplateRef('dialog'); const values = reactive({}); for (const item in props.form) { - values[item] = props.form[item].default ?? null; + if ('default' in props.form[item]) { + values[item] = props.form[item].default ?? null; + } else { + values[item] = null; + } } function ok() { @@ -115,4 +119,20 @@ function cancel() { }); dialog.value?.close(); } + +function getEnumLabel(e: EnumItem) { + return typeof e === 'string' ? e : e.label; +} + +function getEnumValue(e: EnumItem) { + return typeof e === 'string' ? e : e.value; +} + +function getEnumKey(e: EnumItem) { + return typeof e === 'string' ? e : typeof e.value === 'string' ? e.value : JSON.stringify(e.value); +} + +function getRadioKey(e: RadioFormItem['options'][number]) { + return typeof e.value === 'string' ? e.value : JSON.stringify(e.value); +} diff --git a/packages/frontend/src/components/MkInput.vue b/packages/frontend/src/components/MkInput.vue index cc7ad8bb78..12860dd134 100644 --- a/packages/frontend/src/components/MkInput.vue +++ b/packages/frontend/src/components/MkInput.vue @@ -43,7 +43,15 @@ SPDX-License-Identifier: AGPL-3.0-only - + + diff --git a/packages/frontend/src/components/MkServerSetupWizard.vue b/packages/frontend/src/components/MkServerSetupWizard.vue index e6c75d09f0..023bb4bf46 100644 --- a/packages/frontend/src/components/MkServerSetupWizard.vue +++ b/packages/frontend/src/components/MkServerSetupWizard.vue @@ -134,7 +134,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._serverSettings.entrancePageStyle }}:
-
{{ serverSettings.clientOptions.entrancePageStyle }}
+
{{ serverSettings.clientOptions?.entrancePageStyle }}
@@ -240,12 +240,12 @@ const serverSettings = computed(() => { enableReactionsBuffering, clientOptions: { entrancePageStyle: q_use.value === 'open' ? 'classic' : 'simple', - }, + } as any, }; }); -const defaultPolicies = computed>>(() => { - let driveCapacityMb; +const defaultPolicies = computed>(() => { + let driveCapacityMb: Misskey.entities.RolePolicies['driveCapacityMb'] | undefined; if (q_use.value === 'single') { driveCapacityMb = 8192; } else if (q_use.value === 'group') { @@ -254,7 +254,7 @@ const defaultPolicies = computed { diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue index 0f8713d4af..68ba09980a 100644 --- a/packages/frontend/src/components/MkSignupDialog.form.vue +++ b/packages/frontend/src/components/MkSignupDialog.form.vue @@ -66,7 +66,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +