feat(api): add writeTextFile and (path, contents, options) overload (#4228)

This commit is contained in:
Lucas Fernandes Nogueira 2022-05-29 06:10:41 -07:00 committed by GitHub
parent f685df399a
commit 3f998ca294
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 192 additions and 106 deletions

View File

@ -0,0 +1,5 @@
---
"api": patch
---
Renamed `writeFile` to `writeTextFile` but kept the original function for backwards compatibility.

View 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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3052,7 +3052,7 @@ dependencies = [
[[package]]
name = "tauri"
version = "1.0.0-rc.13"
version = "1.0.0-rc.14"
dependencies = [
"anyhow",
"attohttpc",
@ -3102,6 +3102,7 @@ dependencies = [
"tauri-utils",
"tempfile",
"thiserror",
"time",
"tokio",
"url",
"uuid 1.0.0",
@ -3113,7 +3114,7 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "1.0.0-rc.10"
version = "1.0.0-rc.12"
dependencies = [
"anyhow",
"cargo_toml",
@ -3127,7 +3128,7 @@ dependencies = [
[[package]]
name = "tauri-codegen"
version = "1.0.0-rc.7"
version = "1.0.0-rc.8"
dependencies = [
"base64",
"brotli",
@ -3136,7 +3137,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"semver 1.0.7",
"semver 1.0.9",
"serde",
"serde_json",
"sha2",
@ -3148,7 +3149,7 @@ dependencies = [
[[package]]
name = "tauri-macros"
version = "1.0.0-rc.7"
version = "1.0.0-rc.8"
dependencies = [
"heck 0.4.0",
"proc-macro2",
@ -3194,7 +3195,7 @@ dependencies = [
[[package]]
name = "tauri-utils"
version = "1.0.0-rc.7"
version = "1.0.0-rc.8"
dependencies = [
"aes-gcm",
"brotli",
@ -3209,7 +3210,7 @@ dependencies = [
"phf 0.10.1",
"proc-macro2",
"quote",
"semver 1.0.7",
"semver 1.0.9",
"serde",
"serde_json",
"serde_with",

View File

@ -1,78 +1,77 @@
<script>
import { readBinaryFile, readDir, Dir } from "@tauri-apps/api/fs";
import { convertFileSrc } from "@tauri-apps/api/tauri";
import {
readBinaryFile,
writeTextFile,
readDir,
Dir
} from '@tauri-apps/api/fs'
import { convertFileSrc } from '@tauri-apps/api/tauri'
export let onMessage;
export let insecureRenderHtml;
export let onMessage
export let insecureRenderHtml
let pathToRead = "";
let img;
let pathToRead = ''
let img
function getDir() {
const dirSelect = document.getElementById("dir");
return dirSelect.value ? parseInt(dir.value) : null;
const dirSelect = document.getElementById('dir')
return dirSelect.value ? parseInt(dir.value) : null
}
function arrayBufferToBase64(buffer, callback) {
const blob = new Blob([buffer], {
type: "application/octet-binary",
});
const reader = new FileReader();
type: 'application/octet-binary'
})
const reader = new FileReader()
reader.onload = function (evt) {
const dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(",") + 1));
};
reader.readAsDataURL(blob);
const dataurl = evt.target.result
callback(dataurl.substr(dataurl.indexOf(',') + 1))
}
reader.readAsDataURL(blob)
}
const DirOptions = Object.keys(Dir)
.filter((key) => isNaN(parseInt(key)))
.map((dir) => [dir, Dir[dir]]);
.map((dir) => [dir, Dir[dir]])
function read() {
const isFile = pathToRead.match(/\S+\.\S+$/g);
const isFile = pathToRead.match(/\S+\.\S+$/g)
const opts = {
dir: getDir(),
};
dir: getDir()
}
const promise = isFile
? readBinaryFile(pathToRead, opts)
: readDir(pathToRead, opts);
: readDir(pathToRead, opts)
promise
.then(function (response) {
if (isFile) {
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
arrayBufferToBase64(new Uint8Array(response), function (base64) {
const src = "data:image/png;base64," + base64;
insecureRenderHtml('<img src="' + src + '"></img>');
});
const src = 'data:image/png;base64,' + base64
insecureRenderHtml('<img src="' + src + '"></img>')
})
} else {
const value = String.fromCharCode.apply(null, response);
const value = String.fromCharCode.apply(null, response)
insecureRenderHtml(
'<textarea id="file-response"></textarea><button id="file-save">Save</button>'
);
)
setTimeout(() => {
const fileInput = document.getElementById("file-response");
fileInput.value = value;
const fileInput = document.getElementById('file-response')
fileInput.value = value
document
.getElementById("file-save")
.addEventListener("click", function () {
writeFile(
{
file: pathToRead,
contents: fileInput.value,
},
{
dir: getDir(),
}
).catch(onMessage);
});
});
.getElementById('file-save')
.addEventListener('click', function () {
writeTextFile(pathToRead, fileInput.value, {
dir: getDir()
}).catch(onMessage)
})
})
}
} else {
onMessage(response);
onMessage(response)
}
})
.catch(onMessage);
.catch(onMessage)
}
function setSrc() {
@ -95,5 +94,5 @@
<button class="button" id="read">Read</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>

View File

@ -23,9 +23,9 @@
svelte-hmr "^0.14.7"
"@tauri-apps/api@../../tooling/api/dist":
version "1.0.0-rc.3"
version "1.0.0-rc.6"
dependencies:
type-fest "2.12.2"
type-fest "2.13.0"
"@zerodevx/svelte-json-view@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"
integrity sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==
type-fest@2.12.2:
version "2.12.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.2.tgz#80a53614e6b9b475eb9077472fb7498dc7aa51d0"
integrity sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==
type-fest@2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.13.0.tgz#d1ecee38af29eb2e863b22299a3d68ef30d2abfb"
integrity sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==
vite@^2.6.4:
version "2.6.14"

View File

@ -207,6 +207,11 @@ async function confirm(
})
}
export type { DialogFilter, OpenDialogOptions, SaveDialogOptions }
export type {
DialogFilter,
OpenDialogOptions,
SaveDialogOptions,
MessageDialogOptions
}
export { open, save, message, ask, confirm }

View File

@ -96,6 +96,7 @@ export enum BaseDirectory {
interface FsOptions {
dir?: BaseDirectory
// note that adding fields here needs a change in the writeBinaryFile check
}
interface FsDirOptions {
@ -111,12 +112,14 @@ interface FsTextFileOption {
contents: string
}
type BinaryFileContents = Iterable<number> | ArrayLike<number>
/** Options object used to write a binary data to a file. */
interface FsBinaryFileOption {
/** Path to the file to write. */
path: string
/** The byte array contents. */
contents: Iterable<number> | ArrayLike<number>
contents: BinaryFileContents
}
interface FileEntry {
@ -174,6 +177,32 @@ async function readBinaryFile(
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.
*
@ -181,15 +210,31 @@ async function readBinaryFile(
* @param options Configuration object.
* @returns A promise indicating the success or failure of the operation.
*/
async function writeFile(
file: FsTextFileOption,
options: FsOptions = {}
async function writeTextFile(
path: string | FsTextFileOption,
contents?: string | FsOptions,
options?: FsOptions
): Promise<void> {
if (typeof options === 'object') {
Object.freeze(options)
}
if (typeof file === 'object') {
Object.freeze(file)
if (typeof path === 'object') {
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({
@ -198,11 +243,37 @@ async function writeFile(
cmd: 'writeFile',
path: file.path,
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.
*
@ -211,14 +282,31 @@ async function writeFile(
* @returns A promise indicating the success or failure of the operation.
*/
async function writeBinaryFile(
file: FsBinaryFileOption,
options: FsOptions = {}
path: string | FsBinaryFileOption,
contents?: BinaryFileContents | FsOptions,
options?: FsOptions
): Promise<void> {
if (typeof options === 'object') {
Object.freeze(options)
}
if (typeof file === 'object') {
Object.freeze(file)
if (typeof path === 'object') {
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({
@ -227,7 +315,7 @@ async function writeBinaryFile(
cmd: 'writeFile',
path: file.path,
contents: Array.from(file.contents),
options
options: fileOptions
}
})
}
@ -371,6 +459,7 @@ export type {
FsOptions,
FsDirOptions,
FsTextFileOption,
BinaryFileContents,
FsBinaryFileOption,
FileEntry
}
@ -379,7 +468,8 @@ export {
BaseDirectory as Dir,
readTextFile,
readBinaryFile,
writeFile,
writeTextFile,
writeTextFile as writeFile,
writeBinaryFile,
readDir,
createDir,

View File

@ -431,4 +431,4 @@ export type {
FetchOptions
}
export { getClient, fetch, Body, Client, Response, ResponseType }
export { getClient, fetch, Body, Client, Response, ResponseType, FilePart }

View File

@ -31,13 +31,7 @@
}
return window.__TAURI__.fs
.writeFile(
{
path: 'tauri-test.txt',
contents: contents
},
options
)
.writeTextFile('tauri-test.txt', contents, options)
.then(function (res) {
reply({
cmd: 'writeFile' + commandSuffix