Skip to content

Commit

Permalink
Fix: aiscriptディレクトリ内の型エラー解消と単体テスト (#15191)
Browse files Browse the repository at this point in the history
* AiScript APIの型エラーに対処

* AiScript UI APIのテスト作成

* onInputなどがPromiseを返すように

* AiScript共通APIのテスト作成

* CHANGELOG記載

* 定数のテストをconcurrentに

* vi.mockを使用

* misskeyApiをmisskeyApiUntypedのエイリアスとする

* 期待されるエラーメッセージを修正

* Mk:removeのテスト

* misskeyApiの型を変更
  • Loading branch information
takejohn authored Jan 7, 2025
1 parent f7da2ba commit bbe80af
Show file tree
Hide file tree
Showing 8 changed files with 1,396 additions and 64 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
(Cherry-picked from https://github.com/TeamNijimiss/misskey/commit/800359623e41a662551d774de15b0437b6849bb4)
- Fix: ノート作成画面でファイルの添付可能個数を超えてもノートボタンが押せていた問題を修正
- Fix: 「アカウントを管理」画面で、ユーザー情報の取得に失敗したアカウント(削除されたアカウントなど)が表示されない問題を修正
- Enhance: AiScriptの拡張API関数において引数の型チェックをより厳格に

### Server
- Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように
Expand Down
38 changes: 32 additions & 6 deletions packages/frontend/src/scripts/aiscript/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { utils, values } from '@syuilo/aiscript';
import { errors, utils, values } from '@syuilo/aiscript';
import * as Misskey from 'misskey-js';
import { url, lang } from '@@/js/config.js';
import { assertStringAndIsIn } from './common.js';
import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { $i } from '@/account.js';
import { miLocalStorage } from '@/local-storage.js';
import { customEmojis } from '@/custom-emojis.js';
import { url, lang } from '@@/js/config.js';

const DIALOG_TYPES = [
'error',
'info',
'success',
'warning',
'waiting',
'question',
] as const;

export function aiScriptReadline(q: string): Promise<string> {
return new Promise(ok => {
Expand All @@ -22,15 +32,20 @@ export function aiScriptReadline(q: string): Promise<string> {
});
}

export function createAiScriptEnv(opts) {
export function createAiScriptEnv(opts: { storageKey: string, token?: string }) {
return {
USER_ID: $i ? values.STR($i.id) : values.NULL,
USER_NAME: $i ? values.STR($i.name) : values.NULL,
USER_NAME: $i?.name ? values.STR($i.name) : values.NULL,
USER_USERNAME: $i ? values.STR($i.username) : values.NULL,
CUSTOM_EMOJIS: utils.jsToVal(customEmojis.value),
LOCALE: values.STR(lang),
SERVER_URL: values.STR(url),
'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => {
utils.assertString(title);
utils.assertString(text);
if (type != null) {
assertStringAndIsIn(type, DIALOG_TYPES);
}
await os.alert({
type: type ? type.value : 'info',
title: title.value,
Expand All @@ -39,6 +54,11 @@ export function createAiScriptEnv(opts) {
return values.NULL;
}),
'Mk:confirm': values.FN_NATIVE(async ([title, text, type]) => {
utils.assertString(title);
utils.assertString(text);
if (type != null) {
assertStringAndIsIn(type, DIALOG_TYPES);
}
const confirm = await os.confirm({
type: type ? type.value : 'question',
title: title.value,
Expand All @@ -48,14 +68,20 @@ export function createAiScriptEnv(opts) {
}),
'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => {
utils.assertString(ep);
if (ep.value.includes('://')) throw new Error('invalid endpoint');
if (ep.value.includes('://')) {
throw new errors.AiScriptRuntimeError('invalid endpoint');
}
if (token) {
utils.assertString(token);
// バグがあればundefinedもあり得るため念のため
if (typeof token.value !== 'string') throw new Error('invalid token');
}
const actualToken: string|null = token?.value ?? opts.token ?? null;
return misskeyApi(ep.value, utils.valToJs(param), actualToken).then(res => {
if (param == null) {
throw new errors.AiScriptRuntimeError('expected param');
}
utils.assertObject(param);
return misskeyApi(ep.value, utils.valToJs(param) as object, actualToken).then(res => {
return utils.jsToVal(res);
}, err => {
return values.ERROR('request_failed', utils.jsToVal(err));
Expand Down
15 changes: 15 additions & 0 deletions packages/frontend/src/scripts/aiscript/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { errors, utils, type values } from '@syuilo/aiscript';

export function assertStringAndIsIn<A extends readonly string[]>(value: values.Value | undefined, expects: A): asserts value is values.VStr & { value: A[number] } {
utils.assertString(value);
const str = value.value;
if (!expects.includes(str)) {
const expected = expects.map((expect) => `"${expect}"`).join(', ');
throw new errors.AiScriptRuntimeError(`"${value.value}" is not in ${expected}`);
}
}
Loading

0 comments on commit bbe80af

Please sign in to comment.