diff --git a/src/content/docs/ja/plugin/deep-linking.mdx b/src/content/docs/ja/plugin/deep-linking.mdx new file mode 100644 index 0000000000..97282a2453 --- /dev/null +++ b/src/content/docs/ja/plugin/deep-linking.mdx @@ -0,0 +1,520 @@ +--- +title: Deep Linking(ディープリンク) +description: Tauri アプリケーションを URL のデフォルト・ハンドラーとして設定します。 +plugin: deep-link +i18nReady: true +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import PluginPermissions from '@components/PluginPermissions.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +Tauri アプリケーションを URL のデフォルト・ハンドラーとして設定します。 + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「deep-link(ディープリンク)」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + {' '} + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-deep-link@2.0.0 + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4} + #[cfg_attr(mobile, tauri::mobile_entry_point)] + pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_deep_link::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + + 3. お好みの JavaScript パッケージ・マネージャーを使用して、「JavaScript Guest」バインディングをインストールします: + + + + + + + + +## セットアップ方法 + +### Android + +Android 上のリンクからアプリを開くには、次の二つの方法があります: + +1. **App Links(http/https + host, 検証あり)** + [アプリリンク](https://developer.android.com/training/app-links#android-app-links) を使用する場合、 + 所定の形式でテキスト応答を返す `.well-known/assetlinks.json` エンドポイントを持つサーバーが必要です。 + +```json title=".well-known/assetlinks.json" +[ + { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "$APP_BUNDLE_ID", + "sha256_cert_fingerprints": [ + $CERT_FINGERPRINT + ] + } + } +] +``` + +上記の `$APP_BUNDLE_ID` は [`tauri.conf.json > identifier`] で定義されている値で、 `-` が `_` に置き換えられており、 +`$CERT_FINGERPRINT` はアプリ署名証明書の「SHA256 フィンガープリント」のリストです。 +詳細については、[Android アプリリンクの検証] を参照してください。 + +2. **Custom URI schemes(host 不要、検証不要)** + `myapp://...` のような URI の場合、ファイルをホストすることなくカスタム・スキームを宣言できます。モバイル設定内の `scheme` フィールドを使用し、`host` を省略してください。 + + + +**URI** Uniform Resource Identifiers: 「統一リソース識別子」。インターネット上の情報場所を包括的に示す識別子。サブ・セットとして、「URL」(リソースの場所を識別)と「URN」(リソースの「名前」を識別)の二つがあります。 + +**カスタム・スキーム** custom scheme: アプリが独自(カスタム)に定義する URL で、別のアプリからもアプリ内のリソースを参照可能にする方法。 + + + +### iOS + +iOS 上のリンクからアプリを開くには、次の二つの方法があります: + +1. **Universal Links(https + host, 検証あり)** + [ユニバーサル・リンク] を使用する場合、所定の形式で JSON 応答を行なう `.well-known/apple-app-site-association` エンドポイントを持つサーバーが必要です: + +```json title=".well-known/apple-app-site-association" +{ + "applinks": { + "details": [ + { + "appIDs": ["$DEVELOPMENT_TEAM_ID.$APP_BUNDLE_ID"], + "components": [ + { + "/": "/open/*", + "comment": "Matches any URL whose path starts with /open/" /* 「/open/」で始まるパスで指定された URL に一致 */ + } + ] + } + ] + } +} +``` + +:::note +応答 `Content-Type` ヘッダーは `application/json` でなければなりません。 + +また `.well-known/apple-app-site-association` エンドポイントは HTTPS 経由で提供する必要があります。 +ローカルホストをテストするには、「自己署名 TLS 証明書」を使用して iOS シミュレータにローカルホストをインストールするか、「[ngrok](エングロック)」などのサービスを使用します。 +::: + + + +**ngrok** 読み「エングロック」: ローカルPC(Localhost)上で実行している Web アプリケーションなどをインターネット上に公開(外部公開)できる「トンネル」ツール。《[参考](https://cybersecurity-jp.com/security-words/100348)》 + + + +上記 json にある "appIDs” の `$DEVELOPMENT_TEAM_ID` は `tauri.conf.json > tauri > bundle > iOS > developmentTeam` または `TAURI_APPLE_DEVELOPMENT_TEAM` 環境変数で定義された値であり、 +`$APP_BUNDLE_ID` は [`tauri.conf.json > identifier`](英語版参考資料)で定義された値です。 + +自分のドメインがアプリの関連付けを公開するように適切に設定されているかどうかを確認するには、 +`` 部を実際の自分のホスト名に置き換えて、次のコマンドを実行します: + +```sh +curl -v https://app-site-association.cdn-apple.com/a/v1/ +``` + +詳細については、[applinks.details](https://developer.apple.com/documentation/bundleresources/applinks/details-swift.dictionary) を参照してください。 + +2. **Custom URI schemes(host 不要、検証不要)** + `myapp://...` のような URI の場合、モバイル設定で `"appLink": false` を指定(あるいは削除)してカスタム・スキームを宣言できます。このプラグインは、あなたのアプリの Info.plist に適切な `CFBundleURLTypes` エントリを生成します。`.well-known` ファイルや HTTPS ホストは必要ありません。 + +### デスクトップ + +Linux および Windows では、「deep link」は新しいアプリ・プロセスへのコマンドライン引数として配信されます。 +もし固有のアプリ・インスタンスがイベントを受け取ることを望むのであれば、「deep link」プラグインを「[single instance](インスタンスの単一実行)」プラグインと統合します。 + +- まず、「single instance」プラグインに `deep-link` 機能を追加する必要があります: + +```toml title="src-tauri/Cargo.toml" +[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\"))".dependencies] +tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] } +``` + +- 次に、「single instance」プラグインを、常に最初に登録されるプラグインとなるように設定します: + +```rust title="src-tauri/lib.rs" +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + let mut builder = tauri::Builder::default(); + + #[cfg(desktop)] + { + builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| { + println!("a new app instance was opened with {argv:?} and the deep link event was already triggered"); + // when defining deep link schemes at runtime, you must also check `argv` here + // 実行時に「deep link」スキーム(設定構成)を定義する場合は、ここで `argv` も確認する必要があります。 + })); + } + + builder = builder.plugin(tauri_plugin_deep_link::init()); +} +``` + + + +**argv** argument vector: コマンドラインからプログラムに渡された引数を格納した配列。 + + + +:::warn +ユーザーは、引数に URL を含めることで、自分で擬似的(フェイク)な「deep link」を手動トリガーできます。 +Tauri は、コマンドラインの引数を設定されたスキームと照合してこれを受け入れます訳注が、 +URL が期待している形式と一致しているかどうかを確認する必要はあります。 + +つまり、Tauri は静的に設定されたスキームでの「deep link」のみを処理しますので、 +実行時に登録されたスキームは、[`Env::args_os`] を使用して手動で確認する必要があります。 + + + +**これを受け入れる** 原文 mitigate this: 直訳では「これ(擬似的 deep +link)を緩和する」ですが詳細不明ですので、スキームを緩和・軽減するというような意味として上記訳としています。 + + +::: + +## 設定 + +`tauri.conf.json > plugins > deep-link` には、自分のアプリケーションに関連付けたいモバイル・ドメイン/スキームとデスクトップ・スキームを設定します。 + +### 設定例 + +**モバイル用カスタム・スキーム(サーバー不要):** + +```json title="tauri.conf.json" +{ + "plugins": { + "deep-link": { + "mobile": [ + { + "scheme": ["ovi"], + "appLink": false + } + ] + } + } +} +``` + +これにより、Android および iOS 用に `ovi://*` スキームが登録されます。 + +**App Link / Universal Link(認証済み https + host):** + +```json +{ + "plugins": { + "deep-link": { + "mobile": [ + { + "scheme": ["https"], + "host": "your.website.com" /*自分のホスト・サイト*/, + "pathPrefix": ["/open"], + "appLink": true + } + ] + } + } +} +``` + +これにより、`https://your.website.com/open/*` が「アプリ・リンク/ユニバーサル・リンク」として登録されます。 + +**デスクトップ・カスタム・スキーム:** + +```json +{ + "plugins": { + "deep-link": { + "desktop": { + "schemes": ["something", "my-tauri-app"] + } + } + } +} +``` + +## 使用法 + +「deep link」プラグインは、JavaScript と Rust の両方で利用できます。 + +### Deep Link の応答待機 + + + + +アプリ実行中に「deep link」がアプリを起動すると、「`onOpenUrl` コールバック」が呼び出されます。アプリが deep link 経由で開かれたかどうかを検出するには、アプリ起動時に `getCurrent` を使用します。 + +```javascript +import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { getCurrent, onOpenUrl } = window.__TAURI__.deepLink; を使用できます。 + +const startUrls = await getCurrent(); +if (startUrls) { + // アプリはたぶん deep link 経由で起動されています + // getCurrent の戻り値は onOpenUrl がトリガーされるたびに更新されることにも注意してください。 +} + +await onOpenUrl((urls) => { + console.log('deep link:', urls); +}); +``` + + + + +アプリの実行中に「deep link」がアプリを起動すると、このプラグインの「`on_open_url` クロージャ」が呼び出されます。アプリが deep link 経由で開かれたかどうかを検出するには、アプリ起動時に `get_current` を使用してください。 + +```rust title="src-tauri/src/lib.rs" +use tauri_plugin_deep_link::DeepLinkExt; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_deep_link::init()) + .setup(|app| { + // getCurrent の戻り値は onOpenUrl がトリガーされるたびに更新されることにも注意してください。 + let start_urls = app.deep_link().get_current()?; + if let Some(urls) = start_urls { + // アプリはたぶん deep link 経由で起動されています + println!("deep link URLs: {:?}", urls); + } + + app.deep_link().on_open_url(|event| { + println!("deep link URLs: {:?}", event.urls()); + }); + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + + + + +:::note +「open URL イベント」(URL を開く処理)は、deep link 用の macOS API との互換性が要求された一連の URL のリストによってトリガーされますが、 +ほとんどの場合、アプリは一つの URL だけしか受け取りません。 +::: + +### 実行時に「デスクトップ Deep Link」を登録する + +上記の「[設定](#設定)」の項では、あなたのアプリケーションで「静的 deep link スキーム」を定義する方法について説明しています。 + +Linux および Windows では、`register` という Rust 関数を経由して、実行時にあなたのアプリケーションにスキームを関連付けることも可能です。 + +以下のスニペット事例では、実行時に `my-app` のスキームが登録されます。そして、アプリを初めて実行した後に、 +オペレーティング・システムが、アプリケーションで `my-app://*` にある各 URL を開きます: + +```rust title="src-tauri/src/lib.rs" +use tauri_plugin_deep_link::DeepLinkExt; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_deep_link::init()) + .setup(|app| { + #[cfg(desktop)] + app.deep_link().register("my-app")?; + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + +:::note +実行時に deep link を登録することは、Linux および Windows での開発に役立つはずです。というのも、 +デフォルトでは deep link はアプリがインストールされたときにのみ登録されるためです。 + +AppImage のインストールは、AppImage ランチャーが必要であるため、面倒かもしれません。 + +deep link の登録は実行時に行なうことが望ましいため、Tauri では +実行時にすべての「静的に構成された deep link」を強制的に登録する「ヘルパー関数」も含まれています。 +この関数を呼び出すことで、deep link が開発モードに登録されることも保証されます: + +```rust +#[cfg(any(target_os = "linux", all(debug_assertions, windows)))] +{ + use tauri_plugin_deep_link::DeepLinkExt; + app.deep_link().register_all()?; +} +``` + +::: + + + +**ヘルパー関数** helper function: よく用いられる処理内容を「独自の関数」として定義し、いつでも呼び出せるようにしたもの。同じ内容の処理を何度も記述する必要がなくなり省力化の手助け(ヘルプ)になり、処理コードの再利用や可読性の向上にもつながる仕組みです。 + + + +## テスト + +自分のアプリケーションの deep link をテストする場合には、いくつか注意すべき点があります。 + +### デスクトップ + +deep link は、デスクトップ機にインストールされているアプリケーションに対してのみトリガーされます。 +Linux と Windows では、[`register_all`] という Rust 関数を使用することで、これを回避できます。 +この関数は、現在の実行可能ファイルをトリガーするために構成されたすべてのスキームを登録します: + +```rust title="src-tauri/src/lib.rs" +use tauri_plugin_deep_link::DeepLinkExt; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_deep_link::init()) + .setup(|app| { + #[cfg(any(windows, target_os = "linux"))] + { + use tauri_plugin_deep_link::DeepLinkExt; + app.deep_link().register_all()?; + } + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + +:::note +Linux で deep link をサポートする AppImage をインストールするには、AppImage をオペレーティング・システムに統合するための「AppImage ランチャー」が必要です。 +`register_all` 関数を使用すれば、あなたのアプリ・ユーザーが外部ツールを使用する必要もなく、そのまま、すぐに deep link をサポートできます。 + +AppImage がファイル・システム内の別の場所に移動すると、deep link は実行ファイルへの絶対パスを利用しているので、無効になります。 +このため、実行時にスキームを登録することは、さらに重要になります。 + +詳細については、上記 [実行時に「デスクトップ Deep Link」を登録する](#実行時にデスクトップ-Deep-Linkを登録する) の項を参照してください。 +::: + +:::caution +macOS では、実行時に deep link を登録することができないため、deep link はバンドルされたアプリケーションでのみテストが可能です。 +バンドルされたアプリケーションは、「`/Applications` ディレクトリ」にインストールされていなければなりません。 +::: + +#### Windows + +Windows で deep link をトリガーするには、ブラウザーで `://url` を開くか、ターミナルで次のコマンドを実行します: + +```sh +start ://url +``` + +#### Linux + +Linux で deep link をトリガーするには、ブラウザーで `://url` を開くか、ターミナルで `xdg-open` を実行します: + +```sh +xdg-open ://url +``` + +### iOS + +iOS で app link(アプリリンク)をトリガーするには、ブラウザで `https:///path` URL を開きます。シミュレーターの場合は、`simctl` CLI を利用してターミナルから直接リンクを開くことができます: + +```sh +xcrun simctl openurl booted https:///path +``` + +### Android + +Android で app link(アプリリンク)をトリガーするには、ブラウザで `https:///path` URL を開きます。エミュレータの場合は、`adb` CLI を利用してターミナルから直接リンクを開くことができます: + +```sh +adb shell am start -a android.intent.action.VIEW -d https:///path +``` + +## アクセス権限 Permissions + +デフォルトでは、潜在的に危険なプラグイン・コマンドとそのスコープ(有効範囲)はすべてブロックされており、アクセスできません。これらを有効にするには、`capabilities` 設定でアクセス権限を変更する必要があります。 + +詳細については「[セキュリティ・レベル Capabilities](/ja/security/capabilities/)」の章を参照してください。また、プラグインのアクセス権限を設定するには「[プライグン・アクセス権の使用](/ja/learn/security/using-plugin-permissions/)」の章のステップ・バイ・ステップ・ガイドを参照してください。 + +```json title="src-tauri/capabilities/default.json" ins={9} +{ + "$schema": "../gen/schemas/mobile-schema.json", + "identifier": "mobile-capability", + "windows": ["main"], + "platforms": ["iOS", "android"], + "permissions": [ + // 通常、deep link をリッスン(応答待機)するには、「core:event:default」が必要です。 + "core:event:default", + "deep-link:default" + ] +} +``` + + + +[`tauri.conf.json > identifier`]: /reference/config/#identifier +[Android アプリリンクの検証]: https://developer.android.com/training/app-links/verify-android-applinks#web-assoc +[ユニバーサル・リンク]: https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content?language=objc +[single instance]: /plugin/single-instance/ +[`register_all`]: https://docs.rs/tauri-plugin-deep-link/2.0.0/tauri_plugin_deep_link/struct.DeepLink.html#method.register_all +[ngrok]: https://ngrok.com/ +[`Env::args_os`]: https://docs.rs/tauri/2.0.0/tauri/struct.Env.html#structfield.args_os + +
+ 【※ この日本語版は、「Sep 29, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/plugin/dialog.mdx b/src/content/docs/ja/plugin/dialog.mdx new file mode 100644 index 0000000000..0391b682da --- /dev/null +++ b/src/content/docs/ja/plugin/dialog.mdx @@ -0,0 +1,347 @@ +--- +title: Dialog(ダイアログ) +description: メッセージ・ダイアログを伴う「ファイルを開く/保存する」操作のためのネイティブ・システム・ダイアログ。 +i18nReady: true +tableOfContents: + maxHeadingLevel: 4 +plugin: dialog +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import PluginPermissions from '@components/PluginPermissions.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +メッセージ・ダイアログを伴う「ファイルを開く/保存する」操作のためのネイティブ・システム・ダイアログ。 + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「dialog(ダイアログ)」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-dialog + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4} + #[cfg_attr(mobile, tauri::mobile_entry_point)] + pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_dialog::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + + 3. JavaScript でダイアログを作成したい場合には、npm パッケージもインストールしてください: + + + + + + + + +## 使用法 + +「ダイアログ dialog」プラグインは JavaScript と Rust の両方で利用可能です。使い方は以下のとおりです: + +JavaScript では: + +- [対応プラットフォーム](#対応プラットフォーム) +- [セットアップ](#セットアップ) +- [使用法](#使用法) + - [JavaScript](#javascript) + - [「Yes/No」ダイアログの作成](#yesnoダイアログの作成) + - [「Ok/Cancel」ダイアログの作成](#okcancelダイアログの作成) + - [「メッセージ / Message」ダイアログの作成](#メッセージ--messageダイアログの作成) + - [「ファイル・セレクター / File Selector」ダイアログの表示](#ファイルセレクター--file-selectorダイアログの表示) + - [「ファイルへ保存 / Save to File」ダイアログ](#ファイルへ保存--save-to-fileダイアログ) + - [Rust](#rust) + - [「質問 / Ask」ダイアログの生成](#質問--askダイアログの生成) + - [「メッセージ / Message」ダイアログの生成](#メッセージ--messageダイアログの生成) + - [「ファイル・セレクタ / File Selector」ダイアログの生成](#ファイルセレクタ--file-selectorダイアログの生成) + - [Pick Files(ファイルの選択)](#pick-filesファイルの選択) + - [Save Files(ファイルの保存)](#save-filesファイルの保存) + +Rust では: + +- [Build an Ask Dialog](#build-an-ask-dialog) +- [Build a Message Dialog](#build-a-message-dialog) +- [Build a File Selector Dialog](#build-a-file-selector-dialog) + +:::note +「ファイル・ダイアログ」API は、Linux、Windows、macOS 上のファイル・システム・パスを返します。 + +iOS では、`file://` URI が返されます。 + +Android では、[コンテンツ URI] が返されます。 + +「[filesystem プラグイン]」は、そのままで、どのようなパス形式でも動作します。 +::: + +### JavaScript + +JavaScript API の『リファレンス(参考資料)』(英語サイト)で、すべての [ダイアログ・オプション](/reference/javascript/dialog/) を参照してください。 + +#### 「Yes/No」ダイアログの作成 + +「`Yes`/はい」ボタンと「`No`/いいえ」ボタンのある質問ダイアログを表示します。 + +```javascript +import { ask } from '@tauri-apps/plugin-dialog'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { ask } = window.__TAURI__.dialog; を使用できます + +// 「Yes/No」ダイアログを作成 +const answer = await ask('This action cannot be reverted. Are you sure?', { + title: 'Tauri', + kind: 'warning', +}); + +console.log(answer); +// コンソールにブール値を出力 +``` + +#### 「Ok/Cancel」ダイアログの作成 + +「`Ok`/OK」ボタンと「`Cancel`/キャンセル」ボタンのある質問ダイアログを表示します。 + +```javascript +import { confirm } from '@tauri-apps/plugin-dialog'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { confirm } = window.__TAURI__.dialog; を使用できます + +// 「Ok/Cancel の確認」ダイアログを作成 +const confirmation = await confirm( + 'This action cannot be reverted. Are you sure?', + { title: 'Tauri', kind: 'warning' } +); + +console.log(confirmation); +// コンソールにブール値を出力 +``` + +#### 「メッセージ / Message」ダイアログの作成 + +「`Ok`/OK」ボタン付きのメッセージ・ダイアログを表示します。ユーザーがこのダイアログを閉じると `false` が返されることに注意してください。 + +```javascript +import { message } from '@tauri-apps/plugin-dialog'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { message } = window.__TAURI__.dialog; を使用できます + +// メッセージを表示 +await message('File not found', { title: 'Tauri', kind: 'error' }); +``` + +#### 「ファイル・セレクター / File Selector」ダイアログの表示 + +「ファイル/ディレクトリ」選択ダイアログを開きます。 + +`multiple` オプションは、このダイアログで「複数の選択を許可するかどうか」を制御し、`directory` オプションは「ディレクトリ選択を許可するかどうか」を制御します。 + +```javascript +import { open } from '@tauri-apps/plugin-dialog'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { open } = window.__TAURI__.dialog; を使用できます + +// ダイアログを表示 +const file = await open({ + multiple: false, + directory: false, +}); +console.log(file); +// 「ファイル・パス」または「URI」を出力 +``` + + + +**URI** Uniform Resource Identifier: 「**統一資源識別子**」。Web上のリソースを識別・認識するための文字列(識別子)の総称。URL と URN はそのサブセット。《[wikipedia](https://ja.wikipedia.org/wiki/Uniform_Resource_Identifier)》 + + + +#### 「ファイルへ保存 / Save to File」ダイアログ + +「ファイル/ディレクトリを保存」ダイアログを開きます。 + +```javascript +import { save } from '@tauri-apps/plugin-dialog'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { save } = window.__TAURI__.dialog; を使用できます + +// 拡張子 .png または .jpeg を付けて「マイフィルター」を保存するように指示を出します +const path = await save({ + filters: [ + { + name: 'My Filter', + extensions: ['png', 'jpeg'], + }, + ], +}); +console.log(path); +// 選択されたパスを出力 +``` + +--- + +### Rust + +利用可能なすべてのオプションを確認するには、[Rust API リファレンス](https://docs.rs/tauri-plugin-dialog/)(英語サイト)を参照してください。 + +#### 「質問 / Ask」ダイアログの生成 + +次の例では `Absolutely` と `Totally` ボタンを含む質問ダイアログを表示します。 + +```rust +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons}; + +let answer = app.dialog() + .message("Tauri is Awesome") + .title("Tauri is Awesome") + .buttons(MessageDialogButtons::OkCancelCustom("Absolutely", "Totally")) + .blocking_show(); +``` + +ノン・ブロッキング操作が必要な場合は、代わりに `show()` を使用できます: + +```rust +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons}; + +app.dialog() + .message("Tauri is Awesome") + .title("Tauri is Awesome") + .buttons(MessageDialogButtons::OkCancelCustom("Absolutely", "Totally")) + .show(|result| match result { + true => // 「true」の場合の処理, + false =>// 「false」の場合の処理, + }); +``` + +#### 「メッセージ / Message」ダイアログの生成 + +`Ok` ボタンのあるメッセージ・ダイアログを表示します。ユーザーがダイアログを閉じると、`false` が返されることに注意してください。 + +```rust +use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; + +let ans = app.dialog() + .message("File not found") + .kind(MessageDialogKind::Error) + .title("Warning") + .blocking_show(); +``` + +ノン・ブロッキング操作が必要な場合は、代わりに `show()` を使用できます: + +```rust +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind}; + +app.dialog() + .message("Tauri is Awesome") + .kind(MessageDialogKind::Info) + .title("Information") + .buttons(MessageDialogButtons::OkCustom("Absolutely")) + .show(|result| match result { + true => // 「true」の場合の処理, + false =>// 「false」の場合の処理, + }); +``` + +#### 「ファイル・セレクタ / File Selector」ダイアログの生成 + +#### Pick Files(ファイルの選択) + +```rust +use tauri_plugin_dialog::DialogExt; + +let file_path = app.dialog().file().blocking_pick_file(); +// file_path `Option` を返し、ユーザーがダイアログを閉じた場合は `None` を返します +``` + +ノン・ブロッキング操作が必要な場合は、代わりに `pick_file()` を使用できます: + +```rust +use tauri_plugin_dialog::DialogExt; + +app.dialog().file().pick_file(|file_path| { + // file_path `Option` を返し、ユーザーがダイアログを閉じた場合は `None` を返します + }) +``` + +#### Save Files(ファイルの保存) + +```rust +use tauri_plugin_dialog::DialogExt; + +let file_path = app + .dialog() + .file() + .add_filter("My Filter", &["png", "jpeg"]) + .blocking_save_file(); + // ここに、オプションのファイルパスを用いて行なう処理を記述 + // ユーザーがダイアログを閉じた場合には、ファイル・パスは「`None`(なし)」になります +``` + +あるいは、その代わりに: + +```rust +use tauri_plugin_dialog::DialogExt; + +app.dialog() + .file() + .add_filter("My Filter", &["png", "jpeg"]) + .pick_file(|file_path| { + // file_path `Option` を返し、ユーザーがダイアログを閉じた場合は `None` を返します + }); +``` + + + +[コンテンツ URI]: https://developer.android.com/guide/topics/providers/content-provider-basics +[filesystem プラグイン]: /ja/plugin/file-system/ + +
+ 【※ この日本語版は、「Nov 1, 2024 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/plugin/file-system.mdx b/src/content/docs/ja/plugin/file-system.mdx new file mode 100644 index 0000000000..3f07474541 --- /dev/null +++ b/src/content/docs/ja/plugin/file-system.mdx @@ -0,0 +1,807 @@ +--- +title: File System(ファイル・システム) +description: ファイル・システムにアクセスします +plugin: fs +i18nReady: true +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import PluginPermissions from '@components/PluginPermissions.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +ファイル・システムにアクセスします。 + +:::note[Rust 側では std::fs または tokio::fs を使用します] + +Rust を通して「ファイル」や「ディレクトリ」を操作したい場合には、従来の Rust のライブラリ (std::fs、tokio::fs など) を使用します。 + +::: + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「fs(ファイル・システム)」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + { ' ' } + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-fs + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4} + #[cfg_attr(mobile, tauri::mobile_entry_point)] + pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_fs::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + + 3. お好みの JavaScript パッケージ・マネージャーを使用して、「JavaScript Guest」バインディングをインストールします: + + + + + + + + +## 設定 + +### Android + +オーディオ、キャッシュ、ドキュメント、ダウンロード、画像、パブリック、またはビデオのディレクトリを使用する場合、アプリは外部ストレージにアクセス可能である必要があります。 + +`gen/android/app/src/main/AndroidManifest.xml` ファイルの中の `manifest` タグに次のアクセス権限を含めてください: + +```xml + + +``` + +### iOS + +Apple 社は、ユーザーのプライバシー保護を強化するために、アプリ開発者に API の使用に対する「承認理由」を明記することを義務付けています。 + +このため、必要な [NSPrivacyAccessedAPICategoryFileTimestamp] キーと [C617.1] 推奨の理由を含む `PrivacyInfo.xcprivacy` ファイルを `src-tauri/gen/apple` フォルダ内に作成してください。 + + + +**承認理由** approved reasons: Apple 社の「API に対する使用承認理由」記載要求は 2024/05/01 から適用されています([参考](https://developer.apple.com/news/upcoming-requirements/?id=05012024a))。その理由・背景は、上記本文内のリンク先にある Apple 社サイト(英語版)に記載されています。以下、その要訳を示します: アプリのコア機能を司る API には、開発者によるものもサードパーティ製 SDK に含まれているものも、デバイスの内部信号にアクセスしてデバイスやユーザーの識別・特定(フィンカープリンティング)に繋がる潜在的な危険性があるため、その API が必要である理由(required reasons for APIs)を確認するための措置。この理由を明示しない場合、App Store でのアプリのアップロードが拒否されます。 + +**C617.1**: API 使用理由コード番号のひとつ。 「[NSPrivacyAccessedAPICategory](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype)」で規定されている API 選定理由コード。「C617.1」は、「アプリ・コンテナ、アプリ・グループ・コンテナ、またはアプリの CloudKit コンテナ内のファイルのタイムスタンプ、サイズ、その他のメタデータにアクセスする」場合に、この理由コードを宣言するものです。 + + + +```xml + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + +``` + +## 使用法 + +「fs(ファイルシステム)」プラグインは JavaScript と Rust の両方で利用可能です。 + +:::caution[Different APIs] +このプラグインは、フロントエンドでは「ファイル操作 API」が機能しますが、バックエンドには一部のリソース(ファイル、ディレクトリなど)のアクセス権限を変更するメソッドのみが提供されます。 + +Rust 側では、[std::fs](https://doc.rust-lang.org/std/fs/struct.File.html) や [tokio::fs](https://docs.rs/tokio/latest/tokio/fs/index.html) などの、 +従来のファイル操作ライブラリが使用できます。 + +::: + + + + +```javascript +import { exists, BaseDirectory } from '@tauri-apps/plugin-fs'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { exists, BaseDirectory } = window.__TAURI__.fs; を使用できます + +// `$APPDATA/avatar.png`ファイルが存在するかどうかを確認します +await exists('avatar.png', { baseDir: BaseDirectory.AppData }); +``` + + + + +```rust title="src-tauri/src/lib.rs" +use tauri_plugin_fs::FsExt; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_fs::init()) + .setup(|app| { + // allowed the given directory + let scope = app.fs_scope(); + scope.allow_directory("/path/to/directory", false); + dbg!(scope.allowed()); + + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + + + + +## セキュリティ + +このモジュールは「パス・トラバーサル」を防止し、親ディレクトリへの「アクセサ」メソッドの使用を許可しません +(つまり、「/usr/path/to/../file」や「../path/to/file」へのパスは許可されません)。 +この API を使用してアクセスされるパスは、[ベース・ディレクトリ] のどれかひとつに関連しているか、[path API] を使用して作成されている必要があります。 + + + +**パス・トラバーサル** path traversal: 「ディレクトリ・トラバーサル」とも呼ばれるコンピュータ・システムへの攻撃手法。ユーザーが指定したファイル名のセキュリティ検証または無害化が不十分なことを悪用し、攻撃者がファイル・システム API に対し、本来アクセスできない「親(別)ディレクトリへの移動(トラバース)」を可能にするパス情報を与えることで、システム内の別の場所にあるパスワードや個人情報を奪取するもの。《[wikipedia](https://ja.wikipedia.org/wiki/ディレクトリトラバーサル)》 + +**アクセサ** accessor: オブジェクトの中のプロパティの値を取り出したり、変更したりする関数(メソッド)のこと。 + + + +詳しくは、[@tauri-apps/plugin-fs - Security](英語サイト)をご覧ください。 + +## パス Paths + +「ファイル・システム」プラグインは、パスを操作するための二つの方法(「ベース・ディレクトリ」と「[path API]」)を提供しています。 + +- ベース・ディレクトリ + + 操作の作業ディレクトリとして機能する [baseDir][ベース・ディレクトリ] ​​が定義できるオプション引数が、どの API にもあります。 + + ```js + import { readFile } from '@tauri-apps/plugin-fs'; + const contents = await readFile('avatars/tauri.png', { + baseDir: BaseDirectory.Home, + }); + ``` + + 上記の例では、「**Home** ベース・ディレクトリ」を使用しているため、~/avatars/tauri.png ファイルが読み取られます。 + +- path API(パス API) + + 別の方法として、「パス API」を使用してパス操作を実行することもできます。 + + ```js + import { readFile } from '@tauri-apps/plugin-fs'; + import * as path from '@tauri-apps/api/path'; + const home = await path.homeDir(); + const contents = await readFile(await path.join(home, 'avatars/tauri.png')); + ``` + +## ファイル Files + +### Create(作成) + +この操作では、ファイルを作成し、そのハンドル(識別子)を返します。ファイルが既に存在する場合は、切り捨てられます。 + +```js +import { create, BaseDirectory } from '@tauri-apps/plugin-fs'; +const file = await create('foo/bar.txt', { baseDir: BaseDirectory.AppData }); +await file.write(new TextEncoder().encode('Hello world')); +await file.close(); +``` + +:::note +ファイルの操作が完了したら、常に `file.close()` を呼び出してください。 +::: + +### Write(書き込み) + +「ファイル・システム」プラグインでは、パフォーマンス向上のために「テキスト・ファイル」と「バイナリ・ファイル」を書き込むために別々の API を提供しています。 + +- テキスト・ファイル + + ```js + import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; + const contents = JSON.stringify({ notifications: true }); + await writeTextFile('config.json', contents, { + baseDir: BaseDirectory.AppConfig, + }); + ``` + +- バイナリ・ファイル + + ```js + import { writeFile, BaseDirectory } from '@tauri-apps/plugin-fs'; + const contents = new Uint8Array(); // fill a byte array + await writeFile('config', contents, { + baseDir: BaseDirectory.AppConfig, + }); + ``` + +### Open(開く) + +この処理では、ファイルを開き、そのハンドルを返します。 +この API を使用すると、ファイルを開く方法をより詳細に制御できます。 +(読み取り専用モード、書き込み専用モード、上書きではなく追加、ファイルが存在しない場合にのみ作成、など)。 + +:::note +ファイルの操作が完了したら、常に `file.close()` を呼び出してください。 +::: + +- 読み取り専用 read-only + + デフォルト・モードです。 + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + read: true, + baseDir: BaseDirectory.AppData, + }); + + const stat = await file.stat(); + const buf = new Uint8Array(stat.size); + await file.read(buf); + const textContents = new TextDecoder().decode(buf); + await file.close(); + ``` + +- 書き込み専用 write-only + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + write: true, + baseDir: BaseDirectory.AppData, + }); + await file.write(new TextEncoder().encode('Hello world')); + await file.close(); + ``` + + デフォルトでは、`file.write()` 呼び出しで、ファイルは切り捨てられます。 + 既存のコンテンツに追加する方法の詳細については、次の例を参照してください。 + +- 追加 append + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + append: true, + baseDir: BaseDirectory.AppData, + }); + await file.write(new TextEncoder().encode('world')); + await file.close(); + ``` + + `{ append: true }` は `{ write: true, append: true }` と同じ効果を持つことに注意してください。 + +- 切り捨て truncate + + `truncate` オプションが設定されていて、しかもファイルがすでに存在する場合、ファイルは長さ「0」に切り捨てられます。 + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + write: true, + truncate: true, + baseDir: BaseDirectory.AppData, + }); + await file.write(new TextEncoder().encode('world')); + await file.close(); + ``` + + このオプションでは、`write` が `true` である必要があります。 + + このオプションは、複数の `file.write()` 呼び出しを使用して既存のファイルを書き換える場合は、`append` オプションと一緒に使用できます。 + +- 作成 create + + デフォルトでは、`open` API は既存のファイルのみを開きます。ファイルが存在しない場合には作成し、存在する場合にはそのファイルを開くようにするには、`create` を `true` に設定してください: + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + write: true, + create: true, + baseDir: BaseDirectory.AppData, + }); + await file.write(new TextEncoder().encode('world')); + await file.close(); + ``` + + ファイルが作成されるようにするには、`write` も `append` も `true` に設定する必要があります。 + + ファイルがすでに存在する場合にファイルを作成しないようにするには、次の `createNew` を参照してください。 + +- 新規作成 createNew + + `createNew` は `create` 同様に動作しますが、ファイルがすでに存在する場合はファイルを作成しません。 + + ```js + import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; + const file = await open('foo/bar.txt', { + write: true, + createNew: true, + baseDir: BaseDirectory.AppData, + }); + await file.write(new TextEncoder().encode('world')); + await file.close(); + ``` + + ファイルが作成されるようにするには、`write` も `true` に設定する必要があります。 + +### Read(読み取り) + +このプラグインは、パフォーマンス向上のために「テキスト・ファイル」と「バイナリ・ファイル」を読み取りに別々の API を提供しています。 + +- テキスト・ファイル + + ```js + import { readTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; + const configToml = await readTextFile('config.toml', { + baseDir: BaseDirectory.AppConfig, + }); + ``` + + ファイルが大きい場合は、`readTextFileLines` API を使用して、ストリーミング(シーケンシャルに「数行ごとの読み出し」を行なうこと)ができます: + + ```typescript + import { readTextFileLines, BaseDirectory } from '@tauri-apps/plugin-fs'; + const lines = await readTextFileLines('app.logs', { + baseDir: BaseDirectory.AppLog, + }); + for await (const line of lines) { + console.log(line); + } + ``` + +- バイナリ・ファイル + + ```js + import { readFile, BaseDirectory } from '@tauri-apps/plugin-fs'; + const icon = await readFile('icon.png', { + baseDir: BaseDirectory.Resources, + }); + ``` + +### Remove(削除) + +ファイルを削除するには `remove()` を呼び出します。ファイルが存在しない場合はエラーが返されます。 + +```js +import { remove, BaseDirectory } from '@tauri-apps/plugin-fs'; +await remove('user.db', { baseDir: BaseDirectory.AppLocalData }); +``` + +### Copy(コピー) + +`copyFile` 関数は、「ソース・パス source path」と「宛先パス destination path」を受け取ります。 +それぞれのベース・ディレクトリを別々に設定する必要があることに注意してください。 + +```js +import { copyFile, BaseDirectory } from '@tauri-apps/plugin-fs'; +await copyFile('user.db', 'user.db.bk', { + fromPathBaseDir: BaseDirectory.AppLocalData, + toPathBaseDir: BaseDirectory.Temp, +}); +``` + +上記の例では、「\/user.db」ファイルが「$TMPDIR/user.db.bk」にコピーされます。 + +### Exists(ファイル有無確認) + +ファイルが存在するかどうかを確認するには、`exists()` 関数を使用します。 + +```js +import { exists, BaseDirectory } from '@tauri-apps/plugin-fs'; +const tokenExists = await exists('token', { + baseDir: BaseDirectory.AppLocalData, +}); +``` + +### Metadata(メタデータ) + +ファイルのメタデータは、`stat` および `lstat` 関数を使用して取得できます。 +「`stat` 関数」はシンボリック・リンクを辿ります(実際に指し示しているファイルが「スコープ」で許可されていない場合にはエラーを返します)。 +一方、「`lstat` 関数」はシンボリック・リンクを辿らず、シンボリック・リンク自体の情報を返します。 + + + +**シンボリック・リンク** symlink: 「ソフト・リンク」。コンピュータのディスク上で扱うファイルやディレクトリを、本来の位置にファイルを残しつつそれとは別の場所に置いたり別名を付けてアクセスする手段。Windows では「ショートカット」、macOS では「エイリアス」と呼ばれます。《[wikipedia](https://ja.wikipedia.org/wiki/ソフトリンク)》 + + + +```js +import { stat, BaseDirectory } from '@tauri-apps/plugin-fs'; +const metadata = await stat('app.db', { + baseDir: BaseDirectory.AppLocalData, +}); +``` + +### Rename(名前の変更) + +「`rename` 関数」は「ソース・パス」と「宛先パス」を受け取ります。 +それぞれのベース・ディレクトリを別々に設定する必要があることに注意してください。 + +```js +import { rename, BaseDirectory } from '@tauri-apps/plugin-fs'; +await rename('user.db.bk', 'user.db', { + fromPathBaseDir: BaseDirectory.AppLocalData, + toPathBaseDir: BaseDirectory.Temp, +}); +``` + +上記の例では、「\/user.db.bk」ファイルの名前が「$TMPDIR/user.db」に変更されます。 + +### Truncate(切り捨て) + +指定されたファイルを、指定されたファイルの長さ(デフォルトは「0」)に達するまで「切り捨て」るか「拡張」します。 + +- 「長さ 0」に切り捨て + +```typescript +import { truncate } from '@tauri-apps/plugin-fs'; +await truncate('my_file.txt', 0, { baseDir: BaseDirectory.AppLocalData }); +``` + +- 「指定の長さ」に切り捨て + +```typescript +import { + truncate, + readTextFile, + writeTextFile, + BaseDirectory, +} from '@tauri-apps/plugin-fs'; + +const filePath = 'file.txt'; +await writeTextFile(filePath, 'Hello World', { + baseDir: BaseDirectory.AppLocalData, +}); +await truncate(filePath, 7, { + baseDir: BaseDirectory.AppLocalData, +}); +const data = await readTextFile(filePath, { + baseDir: BaseDirectory.AppLocalData, +}); +console.log(data); // "Hello W"(「Hello World」を「7」文字で切り捨て) +``` + +## ディレクトリ Directories + +### Create(作成) + +ディレクトリを作成するには、「`mkdir` 関数」を呼び出します: + +```js +import { mkdir, BaseDirectory } from '@tauri-apps/plugin-fs'; +await mkdir('images', { + baseDir: BaseDirectory.AppLocalData, +}); +``` + +### Read(読み出し) + +「`readDir` 関数」はディレクトリの内容項目を再帰的にリストします: + + + +**再帰的** recursively: 「再帰的に」とは「同じ処理を同じルールで直接の対象とその下位の内容にまで適用する」ことです。たとえば「再帰的にリストする」とは対象のディレクトリの内容とそのサブディレクトリの内容までリストし、『再帰的に削除する」とはその下位のファイルまで削除する、という処理が行なわれます。 + + + +```typescript +import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs'; +const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData }); +``` + +### Remove(削除) + +ディレクトリを削除するには `remove()` を呼び出します。ディレクトリが存在しない場合はエラーが返されます。 + +```js +import { remove, BaseDirectory } from '@tauri-apps/plugin-fs'; +await remove('images', { baseDir: BaseDirectory.AppLocalData }); +``` + +ディレクトリが空でない場合は、`recursive` オプションを `true` に設定する必要があります: + +```js +import { remove, BaseDirectory } from '@tauri-apps/plugin-fs'; +await remove('images', { + baseDir: BaseDirectory.AppLocalData, + recursive: true, +}); +``` + +### Exists(ディレクトリ有無確認) + +ディレクトリが存在するかどうかを確認するには、「`exists()` 関数」を使用します: + +```js +import { exists, BaseDirectory } from '@tauri-apps/plugin-fs'; +const tokenExists = await exists('images', { + baseDir: BaseDirectory.AppLocalData, +}); +``` + +### Metadata(メタデータ) + +ディレクトリのメタデータは、`stat` および `lstat` 関数を使用して取得できます。 +「`stat` 関数」はシンボリック・リンクを辿ります(実際に指し示しているファイルが「スコープ」で許可されていない場合にはエラーを返します)。 +一方、「`lstat` 関数」はシンボリック・リンクを辿らず、シンボリック・リンク自体の情報を返します。 + +```js +import { stat, BaseDirectory } from '@tauri-apps/plugin-fs'; +const metadata = await stat('databases', { + baseDir: BaseDirectory.AppLocalData, +}); +``` + +## 変化の監視 + +ディレクトリまたはファイルの変更を監視するには、`watch` または `watchImmediate` 関数を使用します。 + +- watch(監視)関数 + + 「`watch` 関数」はデバウンスを発生させるため、一定の遅延後にのみイベントが発行されます: + + + +**デバウンス** debounce: キー入力やマウスの移動のような特定のイベントが短時間で連続して発生した際に、各イベントを個別に処理するのではなく、ある一定時間(たとえば 数 100ミリ秒)の間イベントが発生しなかった場合にのみそれまでの処理をまとめて実行する方法。 + + + +```js +import { watch, BaseDirectory } from '@tauri-apps/plugin-fs'; +await watch( + 'app.log', + (event) => { + console.log('app.log event', event); + }, + { + baseDir: BaseDirectory.AppLog, + delayMs: 500, + } +); +``` + +- watchImmediate(即時監視)関数 + + 「`watchImmediate` 関数」は、イベントのリスナーに直ちに通知を行ないます: + + ```js + import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs'; + await watchImmediate( + 'logs', + (event) => { + console.log('logs directory event', event); + }, + { + baseDir: BaseDirectory.AppLog, + recursive: true, + } + ); + ``` + +デフォルトでは、ディレクトリの監視操作は「再帰的」ではありません。 +すべてのサブディレクトリの変更を再帰的に監視するには、`recursive`(再帰)オプションを `true` に設定します。 + +:::note +「watch 関数」には `watch` 機能フラグが必要です: + +```toml title="src-tauri/Cargo.toml" +[dependencies] +tauri-plugin-fs = { version = "2.0.0", features = ["watch"] } +``` + +::: + +## アクセス権限 Permissions + +デフォルトでは、潜在的に危険なプラグイン・コマンドとそのスコープ(有効範囲)はすべてブロックされており、アクセスできません。これらを有効にするには、`capabilities` 設定でアクセス権限を変更する必要があります。 + +詳細については「[セキュリティ・レベル Capabilities](/ja/security/capabilities/)」の章を参照してください。また、プラグインのアクセス権限を設定するには「[プライグン・アクセス権の使用](/ja/learn/security/using-plugin-permissions/)」の章のステップ・バイ・ステップ・ガイドを参照してください。 + +```json title="src-tauri/capabilities/default.json" ins={7-11} +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "main-capability", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "fs:default", + { + "identifier": "fs:allow-exists", + "allow": [{ "path": "$APPDATA/*" }] + } + ] +} +``` + + + +### Scopes(有効範囲) + +このプラグインのアクセス権限には、どのパスが許可されるか、または明示的に拒否されるかを定義するためのスコープ(有効範囲)が含まれています。 + +「スコープ」の詳細については、「[コマンド・スコープ]」を参照してください。 + +「許可 `allow`」または「拒否 `deny`」のスコープのどちらにも、許可または拒否する必要があるすべてのパスをリストした配列を含める必要があります。 +スコープのエントリは「`{ path: string }`」形式です。 + +:::note +「`deny` 指定」は「`allow` 指定」よりも優先されるため、あるパスがスコープによって拒否された場合には、 +別のスコープによって許可されている場合でも、実行時にブロックされます。 +::: + +スコープ・エントリでは、「`$` 変数」を使用して、ホーム・ディレクトリ、アプリ・リソース・ディレクトリ、設定ディレクトリなどの一般的なシステムパスを参照できます。 +以下の表に、参照可能な一般的なパスをすべて示します: + +| Path | 変数 | +| ----------------------------------------------------------------------------------------------- | ------------- | +| [appConfigDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appconfigdir) | $APPCONFIG | +| [appDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appdatadir) | $APPDATA | +| [appLocalDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appLocaldatadir) | $APPLOCALDATA | +| [appcacheDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appcachedir) | $APPCACHE | +| [applogDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#applogdir) | $APPLOG | +| [audioDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#audiodir) | $AUDIO | +| [cacheDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#cachedir) | $CACHE | +| [configDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#configdir) | $CONFIG | +| [dataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#datadir) | $DATA | +| [localDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#localdatadir) | $LOCALDATA | +| [desktopDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#desktopdir) | $DESKTOP | +| [documentDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#documentdir) | $DOCUMENT | +| [downloadDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#downloaddir) | $DOWNLOAD | +| [executableDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#executabledir) | $EXE | +| [fontDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#fontdir) | $FONT | +| [homeDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#homedir) | $HOME | +| [pictureDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#picturedir) | $PICTURE | +| [publicDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#publicdir) | $PUBLIC | +| [runtimeDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#runtimedir) | $RUNTIME | +| [templateDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#templatedir) | $TEMPLATE | +| [videoDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#videodir) | $VIDEO | +| [resourceDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#resourcedir) | $RESOURCE | +| [tempDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#tempdir) | $TEMP | + +#### 設定例 + +- グローバル・スコープ + +どの `fs` コマンドにもスコープを適用するには、「`fs:scope` 権限」を使用します: + +```json title="src-tauri/capabilities/default.json" {7-10} +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "main-capability", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + { + "identifier": "fs:scope", + "allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**/*" }] + } + ] +} +``` + +ある特定の`fs`コマンドだけにスコープを適用するには、 +アクセス権限のオブジェクト形式 `{ "identifier": string, "allow"?: [], "deny"?: [] }` を使用します: + +```json title="src-tauri/capabilities/default.json" {7-18} +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "main-capability", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + { + "identifier": "fs:allow-rename", + "allow": [{ "path": "$HOME/**/*" }] + }, + { + "identifier": "fs:allow-rename", + "deny": [{ "path": "$HOME/.config/**/*" }] + }, + { + "identifier": "fs:allow-exists", + "allow": [{ "path": "$APPDATA/*" }] + } + ] +} +``` + +上記の例では、任意の「`$APPDATA` サブ・パス」(サブ・ディレクトリを含まない)を使用して [`exists`](#existsファイル有無確認) API と [`rename`](#rename名前の変更) を使用します。 + +:::tip +Unix ベースのシステムの「ドット・ファイル」(例:`.gitignore`)あるいは「ドット・フォルダ」(例:`.ssh`)にアクセスしようとしている場合には、 +完全なパス(`/home/user/.ssh/example`)を指定するか、「ドット・フォルダー」のパス・コンポーネントの後ろに「グロブ(ワイルドカード)」を追加する形(`/home/user/.ssh/*`)のいずれかを用いる必要があります。 + + + +**グロブ** glob: 主に Unix 系環境において、ワイルドカードでファイル名のセットを指定するパターンのこと 《[wikipedia](https://ja.wikipedia.org/wiki/グロブ)》 + + + +もしあなたの使用事例でこれが機能しない場合は、任意のコンポーネントを有効な「パス・リテラル」(パスの直接指定値)として扱うようにプラグインを設定してください。 + + + +**パス・リテラル** path literal: リテラルは、プログラミング言語においてソースコード内に値を直接表記した形のものです。パス・リテラルは、ファイルやディレクトリのパスを「文字通りの」文字列として扱うことです。 《[wikipedia](https://ja.wikipedia.org/wiki/リテラル)》 + + + +```json title="src-tauri/tauri.conf.json + "plugins": { + "fs": { + "requireLiteralLeadingDot": false + } + } +``` + +::: + +[NSPrivacyAccessedAPICategoryFileTimestamp]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393 +[C617.1]: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278393 +[ベース・ディレクトリ]: /reference/javascript/api/namespacepath/#basedirectory +[path API]: /reference/javascript/api/namespacepath/ +[@tauri-apps/plugin-fs - Security]: /reference/javascript/fs/#security +[コマンド・スコープ]: /ja/security/scope/ + +
+ 【※ この日本語版は、「Jun 18, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/plugin/global-shortcut.mdx b/src/content/docs/ja/plugin/global-shortcut.mdx new file mode 100644 index 0000000000..fb15392e7b --- /dev/null +++ b/src/content/docs/ja/plugin/global-shortcut.mdx @@ -0,0 +1,172 @@ +--- +title: Global Shortcut(グローバル・ショートカット) +description: グローバル・ショートカットを登録します。 +plugin: global-shortcut +i18nReady: true +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import PluginPermissions from '@components/PluginPermissions.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +グローバルショートカットを登録します。 + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「Global Shortcut グローバル・ショートカット」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + { ' ' } + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-global-shortcut --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4-5} + pub fn run() { + tauri::Builder::default() + .setup(|app| { + #[cfg(desktop)] + app.handle().plugin(tauri_plugin_global_shortcut::Builder::new().build()); + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + + 3. お好みの JavaScript パッケージ・マネージャーを使用して、「JavaScript Guest」バインディングをインストールします: + + + + + + + + +## 使用法 + +「グローバル・ショートカット global-shortcut」プラグインは JavaScript と Rust の両方で利用可能です。 + + + + +```javascript +import { register } from '@tauri-apps/plugin-global-shortcut'; +// `"withGlobalTauri": true` を使用する場合は、 +// const { register } = window.__TAURI__.globalShortcut; を使用できます + +await register('CommandOrControl+Shift+C', () => { + console.log('Shortcut triggered'); +}); +``` + + + + +```rust title="src-tauri/src/lib.rs" +pub fn run() { + tauri::Builder::default() + .setup(|app| { + #[cfg(desktop)] + { + use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, Modifiers, Shortcut, ShortcutState}; + + let ctrl_n_shortcut = Shortcut::new(Some(Modifiers::CONTROL), Code::KeyN); + app.handle().plugin( + tauri_plugin_global_shortcut::Builder::new().with_handler(move |_app, shortcut, event| { + println!("{:?}", shortcut); + if shortcut == &ctrl_n_shortcut { + match event.state() { + ShortcutState::Pressed => { + println!("Ctrl-N Pressed!"); + } + ShortcutState::Released => { + println!("Ctrl-N Released!"); + } + } + } + }) + .build(), + )?; + + app.global_shortcut().register(ctrl_n_shortcut)?; + } + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + + + + +## アクセス権限 Permissions + +デフォルトでは、潜在的に危険なプラグイン・コマンドとそのスコープ(有効範囲)はすべてブロックされており、アクセスできません。これらを有効にするには、`capabilities` 設定でアクセス権限を変更する必要があります。 + +詳細については「[セキュリティ・レベル Capabilities](/ja/security/capabilities/)」の章を参照してください。また、プラグインのアクセス権限を設定するには「[プライグン・アクセス権の使用](/ja/learn/security/using-plugin-permissions/)」の章のステップ・バイ・ステップ・ガイドを参照してください。 + +```json title="src-tauri/capabilities/default.json" ins={7-9} +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "main-capability", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "global-shortcut:allow-is-registered", + "global-shortcut:allow-register", + "global-shortcut:allow-unregister" + ] +} +``` + + + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/plugin/http-client.mdx b/src/content/docs/ja/plugin/http-client.mdx new file mode 100644 index 0000000000..ae04cc7200 --- /dev/null +++ b/src/content/docs/ja/plugin/http-client.mdx @@ -0,0 +1,153 @@ +--- +title: HTTP Client(HTTP クライアント) +description: Rust で記述された HTTP クライアントにアクセスします。 +plugin: http +i18nReady: true +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import PluginPermissions from '@components/PluginPermissions.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +「http プラグイン」を使用して HTTP リクエストを作成します。 + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「HTTP」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-http + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4} + #[cfg_attr(mobile, tauri::mobile_entry_point)] + pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_http::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + 3. JavaScript で http リクエストを行なう場合は、npm パッケージもインストールします: + + + + + + + + +## 使用法 + +「HTTP」プラグインは、JavaScrip と [reqwest](https://docs.rs/reqwest/) の再エクスポート(re-export)としての Rust の両方で利用可能です。 + +### JavaScript + + + +1. 許可されたURLを設定します + + ```json + //src-tauri/capabilities/default.json + { + "permissions": [ + { + "identifier": "http:default", + "allow": [{ "url": "https://*.tauri.app" }], + "deny": [{ "url": "https://private.tauri.app" }] + } + ] + } + ``` + + 詳細については、[アクセス権の概要](/ja/security/permissions/)のドキュメントをご覧ください。 + +2. リクエストの送信 + + 「`fetch`」メソッドは、[`fetch` Web API](https://developer.mozilla.org/ja-JP/docs/Web/API/Fetch_API) の記載内容にできる得るかぎり一致し、準拠するようにします。 + + ```javascript + import { fetch } from '@tauri-apps/plugin-http'; + + // 「GET」リクエストの送信 + const response = await fetch('http://test.tauri.app/data.json', { + method: 'GET', + }); + console.log(response.status); // たとえば 200 + console.log(response.statusText); // たとえば "OK" + ``` + + :::note + + 「[禁止されたリクエスト・ヘッダー]」(英語版サイト)はデフォルトでは無視されます。使用するには、`unsafe-headers` 機能フラグを有効にしておく必要があります: + + ```toml title="src-tauri/Cargo.toml" + [dependencies] + tauri-plugin-http = { version = "2", features = ["unsafe-headers"] } + ``` + + ::: + + + +### Rust + +Rust では、プラグインによって再エクスポートされた「`reqwest` クレート」を利用できます。詳細については、[reqwest のドキュメント](https://docs.rs/reqwest/)(英語サイト)を参照してください。 + +```rust +use tauri_plugin_http::reqwest; + +let res = reqwest::get("http://my.api.host/data.json").await; +println!("{:?}", res.status()); // e.g. 200 +println!("{:?}", res.text().await); // e.g Ok("{ Content }") +``` + + + +[禁止されたリクエスト・ヘッダー]: https://fetch.spec.whatwg.org/#terminology-headers + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/plugin/localhost.mdx b/src/content/docs/ja/plugin/localhost.mdx new file mode 100644 index 0000000000..5bbfa3c2e1 --- /dev/null +++ b/src/content/docs/ja/plugin/localhost.mdx @@ -0,0 +1,103 @@ +--- +title: Localhost(ローカルホスト) +description: 本番環境のアプリで localhost サーバーを使用します。 +plugin: localhost +i18nReady: true +--- + +import PluginLinks from '@components/PluginLinks.astro'; +import Compatibility from '@components/plugins/Compatibility.astro'; + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CommandTabs from '@components/CommandTabs.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + + + +**Plugin 説明内容の英語表記部分について** Plugin 関連の各章は、「Astro Web フレームワーク」により原文データからページ内容の一部が自動生成されているため、英語表記のままの部分があります。 + + + + + +アプリのアセットを公開する際に、デフォルトのカスタム・プロトコルではなく、localhost サーバーを通じて行ないます。 + +:::caution +このプラグインはかなりのセキュリティ・リスクを伴いますので、内容を十分に理解している場合にのみ使用してください。確信が持てない場合には、デフォルトのカスタム・プロトコル実装をご利用ください。 +::: + +## 対応プラットフォーム + + + +## セットアップ + +はじめに、「localhost ローカルホスト」プラグインをインストールしてください。 + + + + + 自分のプロジェクトのパッケージ・マネージャーを使用して依存関係を追加します: + + + + + + + + + 1. `src-tauri` フォルダで次のコマンドを実行して、このプラグインを `Cargo.toml` 内のプロジェクトの依存関係に追加します: + + ```sh frame=none + cargo add tauri-plugin-localhost + ``` + + 2. 追加したプラグインを初期化するために `lib.rs` を修正します: + + ```rust title="src-tauri/src/lib.rs" ins={4} + #[cfg_attr(mobile, tauri::mobile_entry_point)] + pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_localhost::Builder::new().build()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + ``` + + + + + + +## 使用法 + +「localhost」プラグインは Rust で利用できます。 + +```rust title="src-tauri/src/lib.rs" {4} {7-14} +use tauri::{webview::WebviewWindowBuilder, WebviewUrl}; + +pub fn run() { + let port: u16 = 9527; + + tauri::Builder::default() + .plugin(tauri_plugin_localhost::Builder::new(port).build()) + .setup(move |app| { + let url = format!("http://localhost:{}", port).parse().unwrap(); + WebviewWindowBuilder::new(app, "main".to_string(), WebviewUrl::External(url)) + .title("Localhost Example") + .build()?; + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} +``` + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +