Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] Getting access to assets #5225

Closed
seahindeniz opened this issue Sep 18, 2022 · 6 comments
Closed

[feat] Getting access to assets #5225

seahindeniz opened this issue Sep 18, 2022 · 6 comments

Comments

@seahindeniz
Copy link

seahindeniz commented Sep 18, 2022

Describe the problem

I'm trying to copy a file stored inside the app, but I couldn't find a way to achieve. I'm simply using Vite on a project, it basically imports any file into assets directory when I import a file with ?url suffix.

For example, I can import the file like this:

import fileZip from 'the/original/path/file.zip?url';
// fileZip: "/assets/file.b9be33fa.zip"

I assumed that this path would be enough to use it with resolveResource and copy the file as I needed with the following code

import { copyFile, BaseDirectory } from '@tauri-apps/api/fs';
import { resolveResource } from '@tauri-apps/api/path';
import fileZip from 'the/original/path/file.zip?url';
// fileZip: "/assets/file.b9be33fa.zip"

const resourcePath = await resolveResource(fileZip);
// resourcePath: "/Applications/Tempest.app/Contents/MacOS/../Resources/_root_/assets/file.b9be33fa.zip"

await copyFile(resourcePath, 'file.zip', {
  dir: BaseDirectory.Desktop,
});
// throws: "cannot traverse directory, rewrite the path without the use of `../`"

Describe the solution you'd like

To be honest, the easiest solution would be, a new or an existing API which could allow me to access the file like accessing a file on a host and run FS-related actions on it (i.e. copy).

Alternatives considered

As suggested in the help channel on Discord server, I have peeked at app.asset_resolver().get("/abs/path/to/file") suggestion however, the solution that I need is in the JS environment.

Additional context

No response

@FabianLars
Copy link
Member

My suggestion would be to use the resources feature (which would make resolveResource work), especially if the files are large in size.
Otherweise you should be able to access it directly via /assets/file.b9be33fa.zip since it's part of your frontend if included like this.
So for example stuff like img.src and fetch("path") (this one is probablyyy what you need) will just work. Every frontend file is served "normally" just like your html,js,css

@seahindeniz
Copy link
Author

I actually don't need to access the file from frontend, only to copy the asset to a directory (to Desktop f.e.).

I have looked up the resources feature, however, the documentation is not wide or exampled to understand the logic, or I couldn't find the documentation and figure out how to make it work.

So far, I have found these articles and still no way of how to figure
https://tauri.app/v1/api/js/path/#resolveresource
https://tauri.app/v1/api/config/#bundleconfig.resources
https://docs.rs/tauri/1.1.1/tauri/struct.AssetResolver.html

@FabianLars
Copy link
Member

I actually don't need to access the file from frontend, only to copy the asset to a directory (to Desktop f.e.).

Yeah i understood that, but by including it in the distDir folder, it is part of the frontend, which means you'd need to use frontend tech to access it. If we'd create a asset_resolver equivalent for the frontend it would really be not much different from the fetch stuff.
Oh and in case it wasn't clear: asset_resolver is a mechanism to make your frontend files accessible in rust.

I have looked up the resources feature, however, the documentation is not wide or exampled to understand the logic, or I couldn't find the documentation and figure out how to make it work.

There is a WIP guide here https://deploy-preview-893--tauri.netlify.app/v1/guides/building/resources - Feedback would be much appreciated before we merge :) Just keep in mind that it's supposed to be simple and not show every single possibility for now.

A rundown for your specific usecase:

  1. Add the path to the zip file to resouces in tauri.conf.json
  2. Add $RESOURCE/* to the fs scope
  3. request the path via resolveResource
  4. this is your origin path you'll use in copyFile (similar to your code above)

@seahindeniz
Copy link
Author

So far I have tried adding a path to resources field however, seems like it's not like what I have expected.
Here's the resources field

"resources": [
  "../node_modules/@tempest/extension/dist/*"
]

And the FE code

const thePath = await resolveResource('extension');

console.log(thePath);
console.log(await readDir(await resolveResource('')));

Here's the output of the production version:

"/Applications/Tempest.app/Contents/MacOS/../Resources/extension"
"cannot traverse directory, rewrite the path without the use of `../`"

and the development version:

[Log] /Users/sahindeniz/projects/temp/insider-tools-tauri-1/packages/app/src-tauri/target/debug/extension (App.vue, line 65)
[Log] Array (9) (App.vue, line 66)
0 {children: [], name: ".fingerprint", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/.fingerprint"}
1 {children: [], name: "incremental", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/incremental"}
2 {name: "tempest.d", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/tempest.d"}
3 {name: "Tempest", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/Tempest"}
4 {name: ".cargo-lock", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/.cargo-lock"}
5 {children: [], name: "examples", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/examples"}
6 {children: [], name: "deps", path: "/Users/sahindeniz/projects/temp/tauri-apppackages/app/src-tauri/target/debug/deps"}
7 {children: [], name: "_up_", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/_up_"}
8 {children: [], name: "build", path: "/Users/sahindeniz/projects/temp/tauri-app/packages/app/src-tauri/target/debug/build"}

When I check the target directory, I had this
/src-tauri/target/debug/_up_/node_modules/@tempest/extension/dist


At this point, I feel that the resources field should accept a key-value based object where we can define the folder name and the real path to the resource.
So that when I use resolveResource method, it would not return a path which includes ../, like this
/Applications/Tempest.app/Contents/MacOS/../Resources/extension

Resources can be declared as;

"resources": {
  "extension": "../node_modules/@tempest/extension/dist/*"
},

Then we could access it with the following:

const thePath = await resolveResource('extension');
// Which would return the path without the traverse thing `../`

@FabianLars
Copy link
Member

should accept a key-value

We're thinking about something similar for the future, yeah.

the stupid .. is a macos specific bug with an unreleased fix here #5218.
And with that out of the way you'd get the path like resolveResource("../node_modules/@tempest/extension/dist/whatever") a little tedious but it could be made nicer with a helper function or a string var you can concat.

@amrbashir
Copy link
Member

closing as duplicate of #5196 and feel free to open another issue for the resources key-value pair. We discussed that before and it will probably land in v2 along with #4674

@amrbashir amrbashir closed this as not planned Won't fix, can't repro, duplicate, stale Sep 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants