@kubohiroya/turbowarp-extension-security-dialog 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +8 -0
- package/README.ja.md +116 -15
- package/README.md +148 -19
- package/dist/index.cjs +180 -2
- package/dist/index.d.ts +16 -0
- package/dist/index.mjs +180 -2
- package/dist/react.cjs +275 -13
- package/dist/react.d.ts +10 -1
- package/dist/react.mjs +275 -13
- package/package.json +7 -5
- package/styles.css +40 -0
- package/webpack4.css +40 -0
package/NOTICE.md
CHANGED
|
@@ -30,3 +30,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
30
30
|
## Public Editor screenshots
|
|
31
31
|
|
|
32
32
|
`assets/screenshots/required-modes-{en,ja}-20261025.png` are unmodified browser captures of the public Editor on 25 October 2026, showing Camera Source 0.19.3, Asset Cache 0.3.1 and Bubble 0.13.4. Their origin, Editor revisions and hashes are recorded in `assets/screenshots/capture-20261025.json`. The captured UI, icons and banners retain their respective rights holders and applicable licenses; this package does not relicense those elements.
|
|
33
|
+
|
|
34
|
+
`assets/screenshots/localized-descriptions-{en,ja}-20261025.png` are unmodified captures of the updated public Editor on 25 October 2026, showing localized descriptions for Camera Source 0.19.4, Asset Cache 0.3.2 and Bubble 0.13.5. Their origin, revisions and hashes are recorded in `assets/screenshots/localized-descriptions-20261025.json`. The captured UI, icons and banners retain their respective rights holders and applicable licenses.
|
|
35
|
+
|
|
36
|
+
`assets/screenshots/required-approval-{en,ja}-20261028.png` are unmodified captures of the public Editor on 28 October 2026 after the required-mode approval update, showing Camera Source 0.19.4, Asset Cache 0.3.2 and Bubble 0.13.5 with Deny and With sandbox disabled. Their origin, verified distribution hashes, Editor revisions and image hashes are recorded in `assets/screenshots/required-approval-20261028.json`. The captured UI, icons and banners retain their respective rights holders and applicable licenses.
|
|
37
|
+
|
|
38
|
+
`assets/screenshots/preselected-required-{en,ja}-20261028.png` are unmodified captures of the public Editor on 28 October 2026 after automatic preselection was added when all listed extensions require unsandboxed execution. Camera Source 0.19.4, Asset Cache 0.3.2 and Bubble 0.13.5 have Without sandbox preselected and still require OK before execution. Origin, verified distribution hashes, Editor revisions and image hashes are recorded in `assets/screenshots/preselected-required-20261028.json`. The captured UI, icons and banners retain their respective rights holders and applicable licenses.
|
|
39
|
+
|
|
40
|
+
`assets/screenshots/hidden-bulk-required-{en,ja}-20261028.png` are unmodified captures of the public Editor on 28 October 2026 with Without sandbox preselected for all three required extensions and the redundant bulk selection section hidden. Camera Source 0.19.4, Asset Cache 0.3.2 and Bubble 0.13.5 still require OK before execution. Origin, verified distribution hashes, Editor revisions and image hashes are recorded in `assets/screenshots/hidden-bulk-required-20261028.json`. The captured UI, icons and banners retain their respective rights holders and applicable licenses.
|
package/README.ja.md
CHANGED
|
@@ -1,21 +1,103 @@
|
|
|
1
1
|
# turbowarp-extension-security-dialog
|
|
2
2
|
|
|
3
|
-
[English](
|
|
3
|
+
[English](README.md) | 日本語
|
|
4
4
|
|
|
5
5
|
TurboWarpの複数の機能拡張を、1つの一覧で確認するための共通パッケージです。
|
|
6
6
|
関連タスクと受け入れ基準は [scratch-gui #33](https://github.com/kubohiroya/scratch-gui/issues/33) に記録しています。
|
|
7
7
|
|
|
8
|
+
## Pagesのカタログから機能拡張を選択する
|
|
9
|
+
|
|
10
|
+
`ExtensionSelectionList` は既存のバナー・メタデータ・詳細表示を共有し、各行の右端へチェックボックスを1つ表示します。
|
|
11
|
+
TurboWarp Plus一覧の対応範囲は [#28](https://github.com/kubohiroya/turbowarp-extension-security-dialog/issues/28) に記録しています。
|
|
12
|
+
ホスト側でGitHub PagesのJSONをHTTPS取得し、このコンポーネントへ渡します。
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
import {loadExtensionCatalog} from '@kubohiroya/turbowarp-extension-security-dialog';
|
|
16
|
+
import {ExtensionSelectionList} from '@kubohiroya/turbowarp-extension-security-dialog/react';
|
|
17
|
+
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
const entries = await loadExtensionCatalog(
|
|
20
|
+
'https://kubohiroya.github.io/turbowarp-plus-packages/extensions-v1.json',
|
|
21
|
+
controller.signal
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const list = <ExtensionSelectionList entries={entries} locale="ja"
|
|
25
|
+
filterQuery={searchText} loadedIds={loadedExtensionIds} busy={loading}
|
|
26
|
+
onCancel={closeLibrary}
|
|
27
|
+
onComplete={ordered => host.reviewAndLoadInOrder(ordered)} />;
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
例の `host.reviewAndLoadInOrder` はホスト側で実装する実行許可確認・VM読み込み処理です。
|
|
31
|
+
`onComplete` は依存先を先に並べた重複のない配列を返し、`loadedIds` は除外します。
|
|
32
|
+
ある拡張を選ぶと推移的な依存先すべてがchecked・disabledになります。
|
|
33
|
+
親を解除すると依存関係を再計算し、ほかの選択やユーザー自身の明示選択が必要としている拡張は選択を保ちます。
|
|
34
|
+
読み込み済みの行はchecked・disabledです。検索と表示言語を切り替えても選択を保ちます。
|
|
35
|
+
`busy` で選択・フッター操作を無効にします。取得失敗・再試行・カタログの取得中止・VMエラーの表示と、
|
|
36
|
+
読み込み成功に応じた `loadedIds` 更新はホスト側の担当です。
|
|
37
|
+
|
|
38
|
+
各行は「手動で選択」(青)・「依存関係で自動選択」(紫)・「未選択」(中立色)を、背景・左枠・
|
|
39
|
+
アイコン・状態名で区別します。「読み込み済み」も独立した表示です。一覧の上部には凡例を表示します。
|
|
40
|
+
自動選択した行には「Bubble、Sprite に必要」のように、必要としている明示選択元すべてを表示します。
|
|
41
|
+
手動で選んだ拡張がほかの選択元の依存先になった場合も、「手動で選択」を維持し、依存元を併記して
|
|
42
|
+
チェックボックスを解除不可にします。DOMの `data-selection-state` は順に `selected` / `dependency` /
|
|
43
|
+
`unselected` / `loaded` です。
|
|
44
|
+
|
|
45
|
+
任意のカテゴリ定義がある場合、ダッシュボードと同じ順序でカテゴリ見出し(`h2`)を表示します。
|
|
46
|
+
日本語は `titleJa` があれば使用し、なければ `title` にフォールバックします。
|
|
47
|
+
検索で空になったカテゴリは非表示になりますが、選択状態と「詳細」の対象は維持します。
|
|
48
|
+
カテゴリのない旧JSONは従来の平坦な一覧です。カテゴリ付きと未指定の項目が混在する場合、未指定分は
|
|
49
|
+
末尾の「その他の機能拡張」へ表示します。配色はホストのモーダル背景色・文字色に従います。
|
|
50
|
+
強調色は `--twextsec-manual-accent` / `--twextsec-dependency-accent` /
|
|
51
|
+
`--twextsec-unselected-accent` / `--twextsec-loaded-accent` で調整できます。
|
|
52
|
+
|
|
53
|
+
一覧の表示・選択だけでは機能拡張のコードを読み込み・実行しません。
|
|
54
|
+
JSONのメタデータを直ちに表示し、「詳細」を開いたときだけソースを文字列として取得します。
|
|
55
|
+
取得に失敗してもカタログのメタデータと選択は利用できます。
|
|
56
|
+
実行許可確認には `ExtensionSecurityDialog context="catalog"` を使用でき、キャンセル文言が選択一覧へ戻る案内になります。
|
|
57
|
+
既定の `context="project"` はプロジェクト読み込み用の文言を維持します。
|
|
58
|
+
ホストは確定された実行モードと独自のセキュリティ方針を尊重して読み込んでください。
|
|
59
|
+
|
|
60
|
+
JSON契約は `schemaVersion: 1` と `extensions` 配列です。各要素の必須項目は次のとおりです。
|
|
61
|
+
|
|
62
|
+
| 項目 | 内容 |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `id` | ASCII英数字の機能拡張ID |
|
|
65
|
+
| `name` | 表示名 |
|
|
66
|
+
| `version` | 配布バージョン |
|
|
67
|
+
| `url` | バージョン固定の公開済み機能拡張JSへのHTTPS URL |
|
|
68
|
+
| `dependencies` | 同じJSONに含まれる依存先の機能拡張ID配列。npmパッケージ名ではない |
|
|
69
|
+
|
|
70
|
+
`package`・`description`・`descriptions`(`ja`等の小文字言語タグをキーとする説明)・`author`・`license`・
|
|
71
|
+
`banner`・`repository`・`unsandboxed`(例: `required`)は任意のメタデータです。
|
|
72
|
+
完全なJSON例は[英語版のAPI例](README.md#selecting-extensions-from-a-pages-catalog)を参照してください。
|
|
73
|
+
生成側でパッケージ依存を拡張IDへ変換し、ビルド専用パッケージを除外します。
|
|
74
|
+
|
|
75
|
+
カテゴリはトップレベルの任意項目 `categories: [{id, title, titleJa?}]` としてダッシュボード順に定義し、
|
|
76
|
+
各 `extensions[].category` にそのIDを指定します。カテゴリIDの重複・不正な定義・未定義IDの参照は拒否します。
|
|
77
|
+
`parseExtensionCatalog` の返り値は従来どおり配列で、カテゴリ参照は各要素の
|
|
78
|
+
`category: {id, title, titleJa?, order}` へ解決します。`order` は定義の配列順です。
|
|
79
|
+
|
|
80
|
+
`parseExtensionCatalog` は未対応schema、ID/URL重複、存在しない依存先、循環依存、HTTPS以外や認証情報付きのURLを拒否します。
|
|
81
|
+
`resolveExtensionSelection(entries, explicitIds, loadedIds)` はReactなしでも同じ選択集合・依存順を計算します。
|
|
82
|
+
返り値の `requiredBy` は依存先IDをキー、必要としている明示選択元IDの集合を値とするMapです。
|
|
83
|
+
推移的依存・共有依存を含め、選択を解除すると依存元の集合も再計算します。
|
|
84
|
+
`loadExtensionCatalog` は任意のAbortSignalを受け付け、認証情報・Refererを送らずに取得し、HTTP失敗や不正なJSON契約を例外として返します。
|
|
85
|
+
|
|
86
|
+
切り戻しはホストの起動時固定・既定OFFのフラグをOFFにして再読み込みするか、カタログ接続差分をrevertします。
|
|
87
|
+
既存の3つの実行モードを持つセキュリティ確認は、そのまま利用できます。
|
|
88
|
+
|
|
8
89
|
## 公開Editorのスクリーンショット
|
|
9
90
|
|
|
10
|
-
[英語版](./README.md)
|
|
11
|
-
|
|
12
|
-
Camera Source 0.19.
|
|
91
|
+
[英語版](./README.md)と日本語版は、同じダイアログの表示言語を切り替え、ラベルと拡張の説明文を各言語で表示しています。
|
|
92
|
+
全件必須時の自動選択と一括選択欄の非表示に対応した[公開Editor](https://kubohiroya.github.io/turbowarp-extension-data-editor/editor.html?lang=ja)で、
|
|
93
|
+
2026年10月28日にCamera Source 0.19.4・Asset Cache 0.3.2・Bubble 0.13.5を開いた実画面です。
|
|
13
94
|
|
|
14
|
-

|
|
15
96
|
|
|
16
|
-
3拡張とも`Unsandboxed: required
|
|
17
|
-
|
|
18
|
-
|
|
97
|
+
3拡張とも`Unsandboxed: required`を宣言しています。「拒否」と「サンドボックスあり」は無効化され、
|
|
98
|
+
理由が表示されます。「サンドボックスなし」だけが有効で、「動作に必要」と表示します。
|
|
99
|
+
全拡張がこのモードを必要とする場合、全件のメタデータ取得後に選択済みになり、一括選択欄は非表示になります。
|
|
100
|
+
「OK」で続行するか、「キャンセル」でプロジェクトの読み込みを中止します。
|
|
19
101
|
必要なモードの表示は、安全性や配布元の信頼性の認定ではありません。
|
|
20
102
|
|
|
21
103
|
| 機能拡張 | サンドボックスなしが必要な理由 |
|
|
@@ -25,7 +107,7 @@ Camera Source 0.19.3・Asset Cache 0.3.1・Bubble 0.13.4を開いた実画面で
|
|
|
25
107
|
| Bubble | ホストの実行環境と描画機能へ直接アクセスして、ステージ上に重ねた吹き出しや立ち絵を描画・更新します。 |
|
|
26
108
|
|
|
27
109
|
画像はダイアログ部分をブラウザーで直接撮影したもので、加工していません。
|
|
28
|
-
取得元の版・Editor build・画像hashは[撮影台帳](./assets/screenshots/
|
|
110
|
+
取得元の版・Editor build・画像hashは[撮影台帳](./assets/screenshots/hidden-bulk-required-20261028.json)に記録しています。
|
|
29
111
|
|
|
30
112
|
## 連動するパッケージ
|
|
31
113
|
|
|
@@ -186,17 +268,36 @@ HTTP/HTTPSの出所URLは完全なURLを表示し、別タブで開きます。
|
|
|
186
268
|
プレビュー枠内をスクロールして確認できます。ポインターを外すかEscapeで閉じ、選択や詳細状態を保持します。
|
|
187
269
|
メタデータの非同期取得中も実行方法を選べます。ソースの一覧内表示は引き続き「詳細」を押したときだけです。
|
|
188
270
|
|
|
271
|
+
### 機能拡張の説明文の言語
|
|
272
|
+
|
|
273
|
+
拡張コードを実行せず、任意の言語別ヘッダーコメントを読み取ります。
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
// Description: Share one camera stream between extensions.
|
|
277
|
+
// Description[ja]: 1つのカメラ映像を複数の機能拡張で共有します。
|
|
278
|
+
// Description[ja-JP]: 日本語の説明(日本向け)。
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
言語タグの大文字・小文字は区別しません。Editorの言語の完全一致、基底言語、従来の`Description`の順で説明文を選びます。表示中に言語を変えると、ソースを再取得せず説明が切り替わり、許可の選択状態は保たれます。翻訳がない既存の拡張も従来どおり表示できます。
|
|
282
|
+
|
|
283
|
+
同梱メンバーのnoticeにある説明は親バンドルへ混ぜません。HTMLに見える説明も文字列として表示します。独自の`loadInfo`を使う場合は、任意の`ExtensionMetadata.descriptions`へ小文字の言語タグをキーとした説明を渡せます。`getExtensionDescription(metadata, locale)`でも同じ選択処理を利用できます。
|
|
284
|
+
|
|
285
|
+
上の画像は、日本語説明へ対応した公開Editorと公開済みの3拡張を使用しています。英語版では各拡張の従来の`Description`、日本語版では`Description[ja]`を表示します。対応する翻訳がない拡張は元の説明を表示します。説明の言語が変わっても、必要な実行モードや許可の選択は変わりません。パッケージを更新しても、既存SB3に埋め込まれたコードは自動で差し替わりません。
|
|
286
|
+
|
|
189
287
|
## 実行モードの選択
|
|
190
288
|
|
|
191
289
|
個別選択・一括選択・一覧の見出しは、禁止アイコンの「拒否」、盾の「サンドボックスあり」、
|
|
192
290
|
警告の「サンドボックスなし」の順です。アイコンと色は文字ラベルを補助し、安全性の認定には使いません。
|
|
193
291
|
|
|
194
|
-
先頭の宣言コメントに `// Unsandboxed: required`
|
|
195
|
-
|
|
292
|
+
先頭の宣言コメントに `// Unsandboxed: required` があれば、「拒否」と「サンドボックスあり」を無効化して
|
|
293
|
+
理由を表示し、選択できる唯一のモード「サンドボックスなし」に「動作に必要」を付けます。
|
|
294
|
+
選択したモードを「OK」で承認するか、「キャンセル」でプロジェクトの読み込みを中止します。
|
|
196
295
|
この宣言は作者の自己申告であり、未宣言・取得失敗から必須モードを推測しません。
|
|
197
296
|
|
|
198
|
-
|
|
199
|
-
|
|
297
|
+
「拒否」を含む選択の確定はメタデータ取得の完了または失敗後です。全拡張の取得が成功し、すべてが
|
|
298
|
+
この必須モードを宣言していれば、非対応の保存済み選択も含めて「サンドボックスなし」を選択済みにします。
|
|
299
|
+
「OK」を押すまで拡張は実行せず、「キャンセル」で中止できます。取得中・未宣言・任意指定・取得失敗が
|
|
300
|
+
1件でもあれば、この一括初期選択は行いません。混在する一覧では、非対応の選択を解除して選び直しを案内します。
|
|
200
301
|
一括選択は対応する拡張だけに適用し、全件が非対応の一括ボタンは無効化します。
|
|
201
302
|
|
|
202
303
|
## 接続例
|
|
@@ -238,8 +339,8 @@ scratch-guiは既定OFFの起動時フラグで導入し、ホスト独自のセ
|
|
|
238
339
|
## 開発と検証
|
|
239
340
|
|
|
240
341
|
```sh
|
|
241
|
-
|
|
242
|
-
|
|
342
|
+
pnpm install
|
|
343
|
+
pnpm test
|
|
243
344
|
```
|
|
244
345
|
|
|
245
346
|
GUIとの統合では、実VMでの拒否後の表示・保存、エディター初期画面への遷移、
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# turbowarp-extension-security-dialog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [日本語](README.ja.md)
|
|
4
4
|
|
|
5
5
|
A shared package that reviews every custom extension a TurboWarp project is about to load
|
|
6
6
|
in **one single list**, instead of one prompt per extension.
|
|
@@ -9,17 +9,18 @@ Related tasks and acceptance criteria are tracked in
|
|
|
9
9
|
|
|
10
10
|
## Screenshots from the public Editor
|
|
11
11
|
|
|
12
|
-
[English](./README.md) and [Japanese](./README.ja.md) use the same dialog with localized labels.
|
|
13
|
-
This capture shows Camera Source 0.19.
|
|
12
|
+
[English](./README.md) and [Japanese](./README.ja.md) use the same dialog with localized labels and extension descriptions.
|
|
13
|
+
This capture shows Camera Source 0.19.4, Asset Cache 0.3.2 and Bubble 0.13.5 in the
|
|
14
14
|
[public Editor](https://kubohiroya.github.io/turbowarp-extension-data-editor/editor.html?lang=en)
|
|
15
|
-
on
|
|
15
|
+
on 28 October 2026, with **Without sandbox** already selected for all three extensions and the unnecessary bulk selection section hidden.
|
|
16
16
|
|
|
17
|
-

|
|
18
18
|
|
|
19
|
-
All three extensions declare `Unsandboxed: required`. **With sandbox**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
All three extensions declare `Unsandboxed: required`. **Deny** and **With sandbox** are
|
|
20
|
+
disabled, with the reason shown. **Without sandbox** is enabled and marked **Required to run**.
|
|
21
|
+
When every listed extension requires this mode, it is preselected after all metadata loads, and the bulk selection section is hidden.
|
|
22
|
+
Press OK to continue, or **Cancel** to stop loading the project.
|
|
23
|
+
These labels describe execution requirements, not a safety certification.
|
|
23
24
|
|
|
24
25
|
| Extension | Why it needs to run without a sandbox |
|
|
25
26
|
| --- | --- |
|
|
@@ -28,7 +29,7 @@ choice and OK. These labels describe execution requirements, not a safety certif
|
|
|
28
29
|
| Bubble | Accesses the host runtime and renderer directly to draw and update layered speech bubbles and portraits on the stage. |
|
|
29
30
|
|
|
30
31
|
The PNG is an unmodified, modal-only browser capture. Source versions, Editor build and image
|
|
31
|
-
hashes are recorded in [the capture manifest](./assets/screenshots/
|
|
32
|
+
hashes are recorded in [the capture manifest](./assets/screenshots/hidden-bulk-required-20261028.json).
|
|
32
33
|
|
|
33
34
|
## How it fits together
|
|
34
35
|
|
|
@@ -193,21 +194,48 @@ or a file timestamp.
|
|
|
193
194
|
|
|
194
195
|
Run modes remain selectable while metadata is still loading.
|
|
195
196
|
|
|
197
|
+
### Localized extension descriptions
|
|
198
|
+
|
|
199
|
+
The dialog reads optional language-tagged header comments, without evaluating extension code:
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
// Description: Share one camera stream between extensions.
|
|
203
|
+
// Description[ja]: 1つのカメラ映像を複数の機能拡張で共有します。
|
|
204
|
+
// Description[ja-JP]: 日本語の説明(日本向け)。
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Tags are case-insensitive. Display selection uses the exact Editor locale, then its base
|
|
208
|
+
language, then the original `Description`. A locale change updates the text without refetching
|
|
209
|
+
source or changing permission choices. Missing translations keep existing extensions compatible.
|
|
210
|
+
Only the enclosing header is used; bundled member notices cannot supply its translation.
|
|
211
|
+
HTML-looking text is rendered as text. The optional `ExtensionMetadata.descriptions` record uses
|
|
212
|
+
lowercase keys, and `getExtensionDescription(metadata, locale)` exposes the same lookup.
|
|
213
|
+
|
|
214
|
+
The public Editor and the three published bundles shown above support localized descriptions.
|
|
215
|
+
The English capture uses each original `Description`; the Japanese capture uses `Description[ja]`.
|
|
216
|
+
Extensions without a matching translation retain their original description. The selected language
|
|
217
|
+
does not change required modes or permission choices. Updating a package does not replace code
|
|
218
|
+
already embedded in an existing SB3.
|
|
219
|
+
|
|
196
220
|
## Choosing a run mode
|
|
197
221
|
|
|
198
222
|
Per-row choices, the bulk choices and the list heading are ordered: **Deny** (prohibition
|
|
199
223
|
icon), **With sandbox** (shield), **Without sandbox** (warning). Icons and colour support the
|
|
200
224
|
text labels; they are not a safety certification.
|
|
201
225
|
|
|
202
|
-
If the leading declaration comment contains `// Unsandboxed: required`, *With sandbox*
|
|
203
|
-
disabled with the reason shown, and *Without sandbox* is
|
|
204
|
-
|
|
226
|
+
If the leading declaration comment contains `// Unsandboxed: required`, *Deny* and *With sandbox*
|
|
227
|
+
are disabled with the reason shown, and *Without sandbox* is the only available mode, marked
|
|
228
|
+
*Required to run*. Press OK to approve the selected modes, or Cancel to stop loading
|
|
229
|
+
the project. This declaration is the author's own claim; a required mode is never inferred from
|
|
205
230
|
a missing declaration or a failed fetch.
|
|
206
231
|
|
|
207
|
-
A choice
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
232
|
+
A choice, including Deny, is only committed once metadata has loaded or failed. When every
|
|
233
|
+
listed extension has loaded metadata declaring this requirement, *Without sandbox* is
|
|
234
|
+
preselected for all entries, including entries with incompatible saved choices. Nothing runs
|
|
235
|
+
until the user presses OK; Cancel still stops loading the project. Pending, missing, optional
|
|
236
|
+
or failed declarations prevent this batch default. In mixed batches, incompatible choices
|
|
237
|
+
are cleared and the user is asked to choose again. A bulk choice applies only to extensions
|
|
238
|
+
that support it, and a bulk button is disabled when no listed extension does.
|
|
211
239
|
|
|
212
240
|
## Wiring it up
|
|
213
241
|
|
|
@@ -228,6 +256,107 @@ surfacing as a VM error is identified with `isExtensionSecurityCancelled(error)`
|
|
|
228
256
|
Under Webpack 4 with CSS Modules, load `webpack4.css` instead of `styles.css`; root-level
|
|
229
257
|
compatibility entries resolve for older Webpack 4 setups that do not read package exports.
|
|
230
258
|
|
|
259
|
+
## Selecting extensions from a Pages catalog
|
|
260
|
+
|
|
261
|
+
`ExtensionSelectionList` shares the security dialog's banners, metadata and Details view,
|
|
262
|
+
with one checkbox at the right of each row. This API supports the TurboWarp Plus library
|
|
263
|
+
tracked in [#28](https://github.com/kubohiroya/turbowarp-extension-security-dialog/issues/28).
|
|
264
|
+
The host fetches a versioned JSON catalog over HTTPS:
|
|
265
|
+
|
|
266
|
+
```jsx
|
|
267
|
+
import {loadExtensionCatalog} from '@kubohiroya/turbowarp-extension-security-dialog';
|
|
268
|
+
import {ExtensionSelectionList} from '@kubohiroya/turbowarp-extension-security-dialog/react';
|
|
269
|
+
|
|
270
|
+
const controller = new AbortController();
|
|
271
|
+
const entries = await loadExtensionCatalog(
|
|
272
|
+
'https://kubohiroya.github.io/turbowarp-plus-packages/extensions-v1.json',
|
|
273
|
+
controller.signal
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const list = <ExtensionSelectionList entries={entries} locale="en"
|
|
277
|
+
filterQuery={searchText} loadedIds={loadedExtensionIds} busy={loading}
|
|
278
|
+
onCancel={closeLibrary}
|
|
279
|
+
onComplete={ordered => host.reviewAndLoadInOrder(ordered)} />;
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
`host.reviewAndLoadInOrder` represents the host's permission review and VM loading path.
|
|
283
|
+
The callback receives dependencies before their dependants, each once, excluding
|
|
284
|
+
`loadedIds`. Selecting an extension checks and disables all transitive dependencies.
|
|
285
|
+
Removing its selection recomputes the closure; dependencies remain checked if another
|
|
286
|
+
selection needs them or the user selected them explicitly. Loaded rows are checked and
|
|
287
|
+
disabled. Search and locale changes preserve selection. `busy` disables selection and the
|
|
288
|
+
footer controls. The host owns fetch errors, retry, catalog cancellation, VM errors, and
|
|
289
|
+
updating `loadedIds` after each successful load.
|
|
290
|
+
|
|
291
|
+
Rows distinguish **Selected by you** (blue), **Selected automatically** (purple), and
|
|
292
|
+
**Not selected** (neutral), using a background, left border, icon and label together.
|
|
293
|
+
Already loaded rows have their own label and accent. A legend explains the states above
|
|
294
|
+
the list. Automatically selected dependencies name every selected root that needs them,
|
|
295
|
+
for example “Required by Bubble, Sprite”. An explicitly selected dependency keeps its
|
|
296
|
+
“Selected by you” state while another root requires it; its checkbox stays disabled and
|
|
297
|
+
the dependency reason is also shown. The row's `data-selection-state` is `selected`,
|
|
298
|
+
`dependency`, `unselected` or `loaded`.
|
|
299
|
+
|
|
300
|
+
Optional catalog categories render as semantic `h2` sections in dashboard order. Japanese
|
|
301
|
+
uses `titleJa` when available, otherwise `title`; other locales use `title`. Search hides
|
|
302
|
+
empty sections without changing selection or source controls. Catalogs without categories
|
|
303
|
+
keep a flat list. If categorized and uncategorized entries are mixed, the latter appear
|
|
304
|
+
under “Other extensions” at the end. Theme colors use the host's modal background and
|
|
305
|
+
foreground; accent overrides are `--twextsec-manual-accent`, `--twextsec-dependency-accent`,
|
|
306
|
+
`--twextsec-unselected-accent`, and `--twextsec-loaded-accent`.
|
|
307
|
+
|
|
308
|
+
The selection list never loads or runs extension code. Catalog metadata renders immediately;
|
|
309
|
+
only Details fetches the source as text. Source failures leave catalog metadata and selection
|
|
310
|
+
usable. `ExtensionSecurityDialog context="catalog"` provides permission review with cancel
|
|
311
|
+
wording that returns to this list; its default `context="project"` retains project wording.
|
|
312
|
+
The host must respect the committed execution modes and its own security policy.
|
|
313
|
+
|
|
314
|
+
The Pages document has the following contract (`schemaVersion: 1`):
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"schemaVersion": 1,
|
|
319
|
+
"categories": [{"id": "camera", "title": "Camera", "titleJa": "カメラ"}],
|
|
320
|
+
"extensions": [
|
|
321
|
+
{
|
|
322
|
+
"id": "cameraSource",
|
|
323
|
+
"name": "Camera Source",
|
|
324
|
+
"category": "camera",
|
|
325
|
+
"version": "1.2.3",
|
|
326
|
+
"package": "@example/camera-source",
|
|
327
|
+
"url": "https://cdn.jsdelivr.net/npm/@example/camera-source@1.2.3/dist/extension.js",
|
|
328
|
+
"description": "Share a camera stream.",
|
|
329
|
+
"descriptions": {"ja": "カメラ映像を共有します。"},
|
|
330
|
+
"repository": "https://github.com/example/camera-source",
|
|
331
|
+
"banner": "https://example.com/camera-source.svg",
|
|
332
|
+
"unsandboxed": "required",
|
|
333
|
+
"dependencies": []
|
|
334
|
+
}
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
IDs contain ASCII letters and digits. `name`, `version`, `url`, and `dependencies` are
|
|
340
|
+
required. Dependencies are extension IDs in this document, not npm package names;
|
|
341
|
+
the generator resolves package dependencies to these IDs. `package`, descriptions, author,
|
|
342
|
+
license, banner, repository and execution requirement are optional metadata. The generator
|
|
343
|
+
uses version-pinned, published distribution URLs and excludes build-only packages.
|
|
344
|
+
`parseExtensionCatalog` rejects unsupported schemas, duplicate IDs/URLs, missing dependencies,
|
|
345
|
+
cycles, and non-HTTPS or credential-bearing URLs before the UI or VM receives entries.
|
|
346
|
+
`resolveExtensionSelection(entries, explicitIds, loadedIds)` exposes the same closure and
|
|
347
|
+
load order independently of React. Its `requiredBy` map associates each dependency ID with
|
|
348
|
+
a set of the explicit root IDs that require it, including transitive and shared dependencies.
|
|
349
|
+
Optional `categories: [{id, title, titleJa?}]` are declared once, in dashboard order;
|
|
350
|
+
`extensions[].category` references one of those IDs. Duplicate category IDs, invalid
|
|
351
|
+
definitions and unknown references are rejected. `parseExtensionCatalog` retains its array
|
|
352
|
+
return type and resolves each reference to `entry.category: {id, title, titleJa?, order}`.
|
|
353
|
+
`loadExtensionCatalog` accepts an optional AbortSignal,
|
|
354
|
+
omits credentials/referrers, and rejects failed HTTP responses or invalid JSON contracts.
|
|
355
|
+
|
|
356
|
+
To roll back catalog integration, turn off the host's startup flag (off by default) and
|
|
357
|
+
reload, or revert the catalog wiring. The existing three-way security dialog remains
|
|
358
|
+
available without the catalog API.
|
|
359
|
+
|
|
231
360
|
## Stored preferences
|
|
232
361
|
|
|
233
362
|
Preferences are saved only when OK was pressed **and** the project then opened successfully.
|
|
@@ -252,8 +381,8 @@ own security policy take precedence.
|
|
|
252
381
|
## Development and verification
|
|
253
382
|
|
|
254
383
|
```sh
|
|
255
|
-
|
|
256
|
-
|
|
384
|
+
pnpm install
|
|
385
|
+
pnpm test
|
|
257
386
|
```
|
|
258
387
|
|
|
259
388
|
GUI integration additionally verifies display and storage after a real-VM denial, the
|