How to circumvent "getFolder" for "doc.saveAs.jpg()"

I think there’s a few things going on here. You’re passing a full file path to your target function, that (according to the function signature) is supposed to get the path to a folder (not a file). You then create a token of it, but the token is just an identifier, it’s not a file or folder object. Then the function createFile only exists on a folder object. Besides, there’s no method allowing you to create an arbitrary location including previously non-existent subfolders in one go.

I would suggest the following: 1) Assuming you have an existing export folder, you can pass the entry of that folder (if you have only a path you can get an entry via getEntryWithURL, described here). 2) On that folder object you can now call createFile, with the file name (not full path). That function returns an entry to that newly created file, which you can then pass to doc.saveAs.

P.S. You may want to brush up on the docs for accessing and handling files. There are a few concepts that are important to understand and distinguish between:

  • A path to a folder or file (or more generally a URI), is just a string that identifies its location on disk.
  • An ‘entry’ for a file or folder is a proper Javascript object representing a location, with methods to get info about the location or do something with it, e.g. for a folder you can create another folder inside of it or create a file inside of the folder. For an entry you can get a token, but generally it’s a good idea to pass around entries in your code and turn entries into tokens if you need them.
  • A token is (similar to a path) a way to identify a location, but in a somewhat encrypyed way, that informs UXP that you have permission to access that location (or previously gained access). UXP operates on either entries, or tokens. Most of the time batchPlay code requires a token (especially whenever you’re supposed to pass a ‘path’, which is a bit confusing), whereas API functions often require entries. Again you can easily get a token for an entry via createSessionToken, the other way around on the other hand is not easy.

Important: Read API docs carefully to know what a function requires, whether it’s a URI (path), entry or token!

UXP is heavily sandboxed for security reasons. So you don’t get random access to any location on disk. You can get access to a folder or file via:

  • Using getFolder, which brings up a dialog. Importantly, once you have that folder, you have access to any child folder or file or any folder/file you create in there. So in your case it might be acceptable for a user to select a main export folder once and then you operate within that folder subsequently (e.g. create files or subfolders in there).
  • Using getEntryWithURL, specifying a full path to a file or folder. Like you brought up in your own post from recently. This will give you an entry to that folder. This type of random file access however needs permissions to be set in the manifest, as described in this post from a while ago. Note: Obviously you can’t get an entry to a location that does not (or not yet) exist on disk.

In your particular example I would start with getting an entry to your main export location. Something like this:

// Ask the user once:
const mainExportFolder = await fs.getFolder();

// Alternatively get random file access (needs manifest setting):
//const lfs = require("uxp").storage.localFileSystem;
//const mainExportFolder = await lfs.getEntryWithUrl(YOUR_FOLDER_PATH);

Then create your subfolders, no need to ask for permissions again. (You may need some logic to handle the case where the subfolder already exists from a previous export, etc. but that’s up to you). Something like this:

const jpgFolder = await mainExportFolder.createFolder("936x676");

Now you can ask the subfolder to create an entry for the JPG file in the subfolder you just created. Important: this is the file name (with extension), not the full path to it. Something like this:

const jpgFile = await jpgFolder.createFile(fileName, {overwrite: true});

// Save the document, providing file entry:
await doc.saveAs.jpg(jpgFile, ... )
1 Like