95 lines
2.1 KiB
JavaScript
95 lines
2.1 KiB
JavaScript
import { __ID__, devMode, filePath } from "../consts.mjs";
|
|
|
|
const { fetchJsonWithTimeout } = foundry.utils;
|
|
|
|
/**
|
|
* Returns a pseudo-hash for a file. If the browser is in a secure
|
|
* context this will return a true SHA-1 hash of the file, otherwise
|
|
* a random ID is generated using the character set A-Za-z0-9.
|
|
*
|
|
* @param {File} file The file to hash
|
|
*/
|
|
export async function hashFile(file) {
|
|
// Handle fallback when hashing isn't possible
|
|
if (!window.isSecureContext || !crypto.subtle.digest) {
|
|
return foundry.utils.randomID(40);
|
|
};
|
|
|
|
// Actually hash the file since we can
|
|
const bytes = await file.arrayBuffer();
|
|
const buffer = await crypto.subtle.digest(`SHA-1`, bytes);
|
|
|
|
const intArray = new Uint8Array(buffer);
|
|
if (Uint8Array.prototype.toHex) {
|
|
return intArray.toHex();
|
|
};
|
|
return Array.from(intArray)
|
|
.map(b => b.toString(16).padStart(2, `0`))
|
|
.join(``);
|
|
};
|
|
|
|
export async function lastModifiedAt(path) {
|
|
try {
|
|
const response = await fetch(filePath(path), { method: `HEAD` });
|
|
return response.headers.get(`Last-Modified`);
|
|
} catch {
|
|
return null;
|
|
};
|
|
};
|
|
|
|
export async function getFile(path) {
|
|
try {
|
|
return fetchJsonWithTimeout(filePath(path));
|
|
} catch {
|
|
return undefined;
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @param {string} path
|
|
* @param {any} data
|
|
*/
|
|
export async function uploadJson(path, filename, data) {
|
|
const content = JSON.stringify(
|
|
data,
|
|
undefined,
|
|
devMode() ? `\t` : undefined,
|
|
);
|
|
try {
|
|
const file = new File(
|
|
[content],
|
|
filename,
|
|
{ type: `text/plain` },
|
|
);
|
|
await uploadFile(path, file);
|
|
} catch {};
|
|
};
|
|
|
|
export async function uploadFile(path, file) {
|
|
|
|
// uploadPersistent adds "storage" into the path automatically
|
|
if (path.startsWith(`storage/`)) {
|
|
path = path.slice(8);
|
|
};
|
|
if (path.endsWith(`/`)) {
|
|
path = path.slice(0, -1);
|
|
};
|
|
|
|
const picker = foundry.applications.apps.FilePicker.implementation;
|
|
try {
|
|
await picker.uploadPersistent(
|
|
__ID__,
|
|
path,
|
|
file,
|
|
);
|
|
} catch {};
|
|
};
|
|
|
|
export function determineFileExtension(file) {
|
|
for (const [short, long] of Object.entries(CONST.IMAGE_FILE_EXTENSIONS)) {
|
|
if (long === file.type) {
|
|
return short;
|
|
};
|
|
};
|
|
return null;
|
|
};
|