diff --git a/CHANGELOG.md b/CHANGELOG.md index 83d0a3f7d2..f1e863a8f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - Enhance: 広告がMisskeyと同一ドメインの場合はRouterで遷移するように - Enhance: リアクション・いいねの総数を表示するように - Enhance: リアクション受け入れが「いいねのみ」の場合はリアクション絵文字一覧を表示しないように +- Enhance: 設定>プラグインのページからプラグインの簡易的なログやエラーを見られるように + - 実装の都合により、プラグインは1つエラーを起こした時に即時停止するようになりました - Fix: 一部のページ内リンクが正しく動作しない問題を修正 - Fix: 周年の実績が閏年を考慮しない問題を修正 - Fix: ローカルURLのプレビューポップアップが左上に表示される diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 64705868b9..f42fd6587a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1772,6 +1772,7 @@ _plugin: installWarn: "信頼できないプラグインはインストールしないでください。" manage: "プラグインの管理" viewSource: "ソースを表示" + viewLog: "ログを表示" _preferencesBackups: list: "作成したバックアップ" diff --git a/packages/frontend/src/pages/settings/plugin.vue b/packages/frontend/src/pages/settings/plugin.vue index 0ab75b95a2..9804454e66 100644 --- a/packages/frontend/src/pages/settings/plugin.vue +++ b/packages/frontend/src/pages/settings/plugin.vue @@ -41,13 +41,26 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.uninstall }} + + + + +
+
+ {{ i18n.ts.copy }} +
+ + +
+
+
- {{ i18n.ts.copy }} + {{ i18n.ts.copy }}
@@ -74,6 +87,7 @@ import { ColdDeviceStorage } from '@/store.js'; import { unisonReload } from '@/scripts/unison-reload.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; +import { pluginLogs } from '@/plugin.js'; const plugins = ref(ColdDeviceStorage.get('plugins')); @@ -87,8 +101,8 @@ async function uninstall(plugin) { }); } -function copy(plugin) { - copyToClipboard(plugin.src ?? ''); +function copy(text) { + copyToClipboard(text ?? ''); os.success(); } diff --git a/packages/frontend/src/plugin.ts b/packages/frontend/src/plugin.ts index 743cadc36a..81233a5a5e 100644 --- a/packages/frontend/src/plugin.ts +++ b/packages/frontend/src/plugin.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { ref } from 'vue'; import { Interpreter, Parser, utils, values } from '@syuilo/aiscript'; import { aiScriptReadline, createAiScriptEnv } from '@/scripts/aiscript/api.js'; import { inputText } from '@/os.js'; @@ -10,6 +11,7 @@ import { Plugin, noteActions, notePostInterruptors, noteViewInterruptors, postFo const parser = new Parser(); const pluginContexts = new Map(); +export const pluginLogs = ref(new Map()); export async function install(plugin: Plugin): Promise { // 後方互換性のため @@ -22,21 +24,27 @@ export async function install(plugin: Plugin): Promise { in: aiScriptReadline, out: (value): void => { console.log(value); + pluginLogs.value.get(plugin.id).push(utils.reprValue(value)); }, log: (): void => { }, + err: (err): void => { + pluginLogs.value.get(plugin.id).push(`${err}`); + throw err; // install時のtry-catchに反応させる + }, }); initPlugin({ plugin, aiscript }); - try { - await aiscript.exec(parser.parse(plugin.src)); - } catch (err) { - console.error('Plugin install failed:', plugin.name, 'v' + plugin.version); - return; - } - - console.info('Plugin installed:', plugin.name, 'v' + plugin.version); + aiscript.exec(parser.parse(plugin.src)).then( + () => { + console.info('Plugin installed:', plugin.name, 'v' + plugin.version); + }, + (err) => { + console.error('Plugin install failed:', plugin.name, 'v' + plugin.version); + throw err; + }, + ); } function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record { @@ -92,6 +100,7 @@ function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record