mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-15 21:53:59 +03:00
feat(api): add writeTextFile
and (path, contents, options)
overload (#4228)
This commit is contained in:
parent
f685df399a
commit
3f998ca294
5
.changes/write-file-rename.md
Normal file
5
.changes/write-file-rename.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"api": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Renamed `writeFile` to `writeTextFile` but kept the original function for backwards compatibility.
|
5
.changes/write-file-variants.md
Normal file
5
.changes/write-file-variants.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"api": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Added `(path, contents[, options])` overload to the `writeTextFile` and `writeBinaryFile` APIs.
|
File diff suppressed because one or more lines are too long
18
examples/api/dist/assets/index.js
vendored
18
examples/api/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
21
examples/api/dist/assets/vendor.js
vendored
21
examples/api/dist/assets/vendor.js
vendored
File diff suppressed because one or more lines are too long
15
examples/api/src-tauri/Cargo.lock
generated
15
examples/api/src-tauri/Cargo.lock
generated
@ -3052,7 +3052,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri"
|
name = "tauri"
|
||||||
version = "1.0.0-rc.13"
|
version = "1.0.0-rc.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"attohttpc",
|
"attohttpc",
|
||||||
@ -3102,6 +3102,7 @@ dependencies = [
|
|||||||
"tauri-utils",
|
"tauri-utils",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
"uuid 1.0.0",
|
"uuid 1.0.0",
|
||||||
@ -3113,7 +3114,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-build"
|
name = "tauri-build"
|
||||||
version = "1.0.0-rc.10"
|
version = "1.0.0-rc.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
@ -3127,7 +3128,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-codegen"
|
name = "tauri-codegen"
|
||||||
version = "1.0.0-rc.7"
|
version = "1.0.0-rc.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"brotli",
|
"brotli",
|
||||||
@ -3136,7 +3137,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"semver 1.0.7",
|
"semver 1.0.9",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
@ -3148,7 +3149,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-macros"
|
name = "tauri-macros"
|
||||||
version = "1.0.0-rc.7"
|
version = "1.0.0-rc.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -3194,7 +3195,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-utils"
|
name = "tauri-utils"
|
||||||
version = "1.0.0-rc.7"
|
version = "1.0.0-rc.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
"brotli",
|
"brotli",
|
||||||
@ -3209,7 +3210,7 @@ dependencies = [
|
|||||||
"phf 0.10.1",
|
"phf 0.10.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"semver 1.0.7",
|
"semver 1.0.9",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
@ -1,78 +1,77 @@
|
|||||||
<script>
|
<script>
|
||||||
import { readBinaryFile, readDir, Dir } from "@tauri-apps/api/fs";
|
import {
|
||||||
import { convertFileSrc } from "@tauri-apps/api/tauri";
|
readBinaryFile,
|
||||||
|
writeTextFile,
|
||||||
|
readDir,
|
||||||
|
Dir
|
||||||
|
} from '@tauri-apps/api/fs'
|
||||||
|
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||||
|
|
||||||
export let onMessage;
|
export let onMessage
|
||||||
export let insecureRenderHtml;
|
export let insecureRenderHtml
|
||||||
|
|
||||||
let pathToRead = "";
|
let pathToRead = ''
|
||||||
let img;
|
let img
|
||||||
|
|
||||||
function getDir() {
|
function getDir() {
|
||||||
const dirSelect = document.getElementById("dir");
|
const dirSelect = document.getElementById('dir')
|
||||||
return dirSelect.value ? parseInt(dir.value) : null;
|
return dirSelect.value ? parseInt(dir.value) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
function arrayBufferToBase64(buffer, callback) {
|
function arrayBufferToBase64(buffer, callback) {
|
||||||
const blob = new Blob([buffer], {
|
const blob = new Blob([buffer], {
|
||||||
type: "application/octet-binary",
|
type: 'application/octet-binary'
|
||||||
});
|
})
|
||||||
const reader = new FileReader();
|
const reader = new FileReader()
|
||||||
reader.onload = function (evt) {
|
reader.onload = function (evt) {
|
||||||
const dataurl = evt.target.result;
|
const dataurl = evt.target.result
|
||||||
callback(dataurl.substr(dataurl.indexOf(",") + 1));
|
callback(dataurl.substr(dataurl.indexOf(',') + 1))
|
||||||
};
|
}
|
||||||
reader.readAsDataURL(blob);
|
reader.readAsDataURL(blob)
|
||||||
}
|
}
|
||||||
|
|
||||||
const DirOptions = Object.keys(Dir)
|
const DirOptions = Object.keys(Dir)
|
||||||
.filter((key) => isNaN(parseInt(key)))
|
.filter((key) => isNaN(parseInt(key)))
|
||||||
.map((dir) => [dir, Dir[dir]]);
|
.map((dir) => [dir, Dir[dir]])
|
||||||
|
|
||||||
function read() {
|
function read() {
|
||||||
const isFile = pathToRead.match(/\S+\.\S+$/g);
|
const isFile = pathToRead.match(/\S+\.\S+$/g)
|
||||||
const opts = {
|
const opts = {
|
||||||
dir: getDir(),
|
dir: getDir()
|
||||||
};
|
}
|
||||||
const promise = isFile
|
const promise = isFile
|
||||||
? readBinaryFile(pathToRead, opts)
|
? readBinaryFile(pathToRead, opts)
|
||||||
: readDir(pathToRead, opts);
|
: readDir(pathToRead, opts)
|
||||||
promise
|
promise
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
if (isFile) {
|
if (isFile) {
|
||||||
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
|
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
|
||||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||||
const src = "data:image/png;base64," + base64;
|
const src = 'data:image/png;base64,' + base64
|
||||||
insecureRenderHtml('<img src="' + src + '"></img>');
|
insecureRenderHtml('<img src="' + src + '"></img>')
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
const value = String.fromCharCode.apply(null, response);
|
const value = String.fromCharCode.apply(null, response)
|
||||||
insecureRenderHtml(
|
insecureRenderHtml(
|
||||||
'<textarea id="file-response"></textarea><button id="file-save">Save</button>'
|
'<textarea id="file-response"></textarea><button id="file-save">Save</button>'
|
||||||
);
|
)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const fileInput = document.getElementById("file-response");
|
const fileInput = document.getElementById('file-response')
|
||||||
fileInput.value = value;
|
fileInput.value = value
|
||||||
document
|
document
|
||||||
.getElementById("file-save")
|
.getElementById('file-save')
|
||||||
.addEventListener("click", function () {
|
.addEventListener('click', function () {
|
||||||
writeFile(
|
writeTextFile(pathToRead, fileInput.value, {
|
||||||
{
|
dir: getDir()
|
||||||
file: pathToRead,
|
}).catch(onMessage)
|
||||||
contents: fileInput.value,
|
})
|
||||||
},
|
})
|
||||||
{
|
|
||||||
dir: getDir(),
|
|
||||||
}
|
|
||||||
).catch(onMessage);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onMessage(response);
|
onMessage(response)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(onMessage);
|
.catch(onMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSrc() {
|
function setSrc() {
|
||||||
@ -95,5 +94,5 @@
|
|||||||
<button class="button" id="read">Read</button>
|
<button class="button" id="read">Read</button>
|
||||||
<button class="button" type="button" on:click={setSrc}>Use as img src</button>
|
<button class="button" type="button" on:click={setSrc}>Use as img src</button>
|
||||||
|
|
||||||
<img alt="file" bind:this={img}>
|
<img alt="file" bind:this={img} />
|
||||||
</form>
|
</form>
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
svelte-hmr "^0.14.7"
|
svelte-hmr "^0.14.7"
|
||||||
|
|
||||||
"@tauri-apps/api@../../tooling/api/dist":
|
"@tauri-apps/api@../../tooling/api/dist":
|
||||||
version "1.0.0-rc.3"
|
version "1.0.0-rc.6"
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest "2.12.2"
|
type-fest "2.13.0"
|
||||||
|
|
||||||
"@zerodevx/svelte-json-view@0.2.0":
|
"@zerodevx/svelte-json-view@0.2.0":
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
@ -267,10 +267,10 @@ svelte@3.35.0:
|
|||||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.35.0.tgz#e0d0ba60c4852181c2b4fd851194be6fda493e65"
|
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.35.0.tgz#e0d0ba60c4852181c2b4fd851194be6fda493e65"
|
||||||
integrity sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==
|
integrity sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==
|
||||||
|
|
||||||
type-fest@2.12.2:
|
type-fest@2.13.0:
|
||||||
version "2.12.2"
|
version "2.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.2.tgz#80a53614e6b9b475eb9077472fb7498dc7aa51d0"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.13.0.tgz#d1ecee38af29eb2e863b22299a3d68ef30d2abfb"
|
||||||
integrity sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==
|
integrity sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==
|
||||||
|
|
||||||
vite@^2.6.4:
|
vite@^2.6.4:
|
||||||
version "2.6.14"
|
version "2.6.14"
|
||||||
|
@ -207,6 +207,11 @@ async function confirm(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { DialogFilter, OpenDialogOptions, SaveDialogOptions }
|
export type {
|
||||||
|
DialogFilter,
|
||||||
|
OpenDialogOptions,
|
||||||
|
SaveDialogOptions,
|
||||||
|
MessageDialogOptions
|
||||||
|
}
|
||||||
|
|
||||||
export { open, save, message, ask, confirm }
|
export { open, save, message, ask, confirm }
|
||||||
|
@ -96,6 +96,7 @@ export enum BaseDirectory {
|
|||||||
|
|
||||||
interface FsOptions {
|
interface FsOptions {
|
||||||
dir?: BaseDirectory
|
dir?: BaseDirectory
|
||||||
|
// note that adding fields here needs a change in the writeBinaryFile check
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FsDirOptions {
|
interface FsDirOptions {
|
||||||
@ -111,12 +112,14 @@ interface FsTextFileOption {
|
|||||||
contents: string
|
contents: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BinaryFileContents = Iterable<number> | ArrayLike<number>
|
||||||
|
|
||||||
/** Options object used to write a binary data to a file. */
|
/** Options object used to write a binary data to a file. */
|
||||||
interface FsBinaryFileOption {
|
interface FsBinaryFileOption {
|
||||||
/** Path to the file to write. */
|
/** Path to the file to write. */
|
||||||
path: string
|
path: string
|
||||||
/** The byte array contents. */
|
/** The byte array contents. */
|
||||||
contents: Iterable<number> | ArrayLike<number>
|
contents: BinaryFileContents
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FileEntry {
|
interface FileEntry {
|
||||||
@ -174,6 +177,32 @@ async function readBinaryFile(
|
|||||||
return Uint8Array.from(arr)
|
return Uint8Array.from(arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a UTF-8 text file.
|
||||||
|
*
|
||||||
|
* @param path The file path.
|
||||||
|
* @param contents The file contents.
|
||||||
|
* @param options Configuration object.
|
||||||
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
|
*/
|
||||||
|
async function writeTextFile(
|
||||||
|
path: string,
|
||||||
|
contents: string,
|
||||||
|
options?: FsOptions
|
||||||
|
): Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a UTF-8 text file.
|
||||||
|
*
|
||||||
|
* @param file The object containing the file path and contents.
|
||||||
|
* @param options Configuration object.
|
||||||
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
|
*/
|
||||||
|
async function writeTextFile(
|
||||||
|
file: FsTextFileOption,
|
||||||
|
options?: FsOptions
|
||||||
|
): Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a UTF-8 text file.
|
* Writes a UTF-8 text file.
|
||||||
*
|
*
|
||||||
@ -181,15 +210,31 @@ async function readBinaryFile(
|
|||||||
* @param options Configuration object.
|
* @param options Configuration object.
|
||||||
* @returns A promise indicating the success or failure of the operation.
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
*/
|
*/
|
||||||
async function writeFile(
|
async function writeTextFile(
|
||||||
file: FsTextFileOption,
|
path: string | FsTextFileOption,
|
||||||
options: FsOptions = {}
|
contents?: string | FsOptions,
|
||||||
|
options?: FsOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (typeof options === 'object') {
|
if (typeof options === 'object') {
|
||||||
Object.freeze(options)
|
Object.freeze(options)
|
||||||
}
|
}
|
||||||
if (typeof file === 'object') {
|
if (typeof path === 'object') {
|
||||||
Object.freeze(file)
|
Object.freeze(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
const file: FsTextFileOption = { path: '', contents: '' }
|
||||||
|
let fileOptions: FsOptions | undefined = options
|
||||||
|
if (typeof path === 'string') {
|
||||||
|
file.path = path
|
||||||
|
} else {
|
||||||
|
file.path = path.path
|
||||||
|
file.contents = path.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof contents === 'string') {
|
||||||
|
file.contents = contents ?? ''
|
||||||
|
} else {
|
||||||
|
fileOptions = contents
|
||||||
}
|
}
|
||||||
|
|
||||||
return invokeTauriCommand({
|
return invokeTauriCommand({
|
||||||
@ -198,11 +243,37 @@ async function writeFile(
|
|||||||
cmd: 'writeFile',
|
cmd: 'writeFile',
|
||||||
path: file.path,
|
path: file.path,
|
||||||
contents: Array.from(new TextEncoder().encode(file.contents)),
|
contents: Array.from(new TextEncoder().encode(file.contents)),
|
||||||
options
|
options: fileOptions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a byte array content to a file.
|
||||||
|
*
|
||||||
|
* @param path The file path.
|
||||||
|
* @param contents The file contents.
|
||||||
|
* @param options Configuration object.
|
||||||
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
|
*/
|
||||||
|
async function writeBinaryFile(
|
||||||
|
path: string,
|
||||||
|
contents: BinaryFileContents,
|
||||||
|
options?: FsOptions
|
||||||
|
): Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a byte array content to a file.
|
||||||
|
*
|
||||||
|
* @param file The object containing the file path and contents.
|
||||||
|
* @param options Configuration object.
|
||||||
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
|
*/
|
||||||
|
async function writeBinaryFile(
|
||||||
|
file: FsBinaryFileOption,
|
||||||
|
options?: FsOptions
|
||||||
|
): Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a byte array content to a file.
|
* Writes a byte array content to a file.
|
||||||
*
|
*
|
||||||
@ -211,14 +282,31 @@ async function writeFile(
|
|||||||
* @returns A promise indicating the success or failure of the operation.
|
* @returns A promise indicating the success or failure of the operation.
|
||||||
*/
|
*/
|
||||||
async function writeBinaryFile(
|
async function writeBinaryFile(
|
||||||
file: FsBinaryFileOption,
|
path: string | FsBinaryFileOption,
|
||||||
options: FsOptions = {}
|
contents?: BinaryFileContents | FsOptions,
|
||||||
|
options?: FsOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (typeof options === 'object') {
|
if (typeof options === 'object') {
|
||||||
Object.freeze(options)
|
Object.freeze(options)
|
||||||
}
|
}
|
||||||
if (typeof file === 'object') {
|
if (typeof path === 'object') {
|
||||||
Object.freeze(file)
|
Object.freeze(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
const file: FsBinaryFileOption = { path: '', contents: [] }
|
||||||
|
let fileOptions: FsOptions | undefined = options
|
||||||
|
if (typeof path === 'string') {
|
||||||
|
file.path = path
|
||||||
|
} else {
|
||||||
|
file.path = path.path
|
||||||
|
file.contents = path.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contents && 'dir' in contents) {
|
||||||
|
fileOptions = contents
|
||||||
|
} else {
|
||||||
|
// @ts-expect-error
|
||||||
|
file.contents = contents ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
return invokeTauriCommand({
|
return invokeTauriCommand({
|
||||||
@ -227,7 +315,7 @@ async function writeBinaryFile(
|
|||||||
cmd: 'writeFile',
|
cmd: 'writeFile',
|
||||||
path: file.path,
|
path: file.path,
|
||||||
contents: Array.from(file.contents),
|
contents: Array.from(file.contents),
|
||||||
options
|
options: fileOptions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -371,6 +459,7 @@ export type {
|
|||||||
FsOptions,
|
FsOptions,
|
||||||
FsDirOptions,
|
FsDirOptions,
|
||||||
FsTextFileOption,
|
FsTextFileOption,
|
||||||
|
BinaryFileContents,
|
||||||
FsBinaryFileOption,
|
FsBinaryFileOption,
|
||||||
FileEntry
|
FileEntry
|
||||||
}
|
}
|
||||||
@ -379,7 +468,8 @@ export {
|
|||||||
BaseDirectory as Dir,
|
BaseDirectory as Dir,
|
||||||
readTextFile,
|
readTextFile,
|
||||||
readBinaryFile,
|
readBinaryFile,
|
||||||
writeFile,
|
writeTextFile,
|
||||||
|
writeTextFile as writeFile,
|
||||||
writeBinaryFile,
|
writeBinaryFile,
|
||||||
readDir,
|
readDir,
|
||||||
createDir,
|
createDir,
|
||||||
|
@ -431,4 +431,4 @@ export type {
|
|||||||
FetchOptions
|
FetchOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getClient, fetch, Body, Client, Response, ResponseType }
|
export { getClient, fetch, Body, Client, Response, ResponseType, FilePart }
|
||||||
|
@ -31,13 +31,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return window.__TAURI__.fs
|
return window.__TAURI__.fs
|
||||||
.writeFile(
|
.writeTextFile('tauri-test.txt', contents, options)
|
||||||
{
|
|
||||||
path: 'tauri-test.txt',
|
|
||||||
contents: contents
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
reply({
|
reply({
|
||||||
cmd: 'writeFile' + commandSuffix
|
cmd: 'writeFile' + commandSuffix
|
||||||
|
Loading…
Reference in New Issue
Block a user