(() => {
var plugin = {
corsProxies: [
"https://amplenote-plugins-cors-anywhere.onrender.com/",
"https://cors-anywhere.herokuapp.com/",
"https://api.allorigins.win/raw?url=",
"https://corsproxy.io/?"
],
imageOption: {
"Save image to Amplenote": {
run: async function(app, image) {
try {
let src = image.src, dataURL = await plugin.retry(() => plugin._dataURLFromImageURL(src)), sourceNoteHandle = await app.findNote({ uuid: app.context.noteUUID }), fileURL = await app.attachNoteMedia(sourceNoteHandle, dataURL);
await app.context.updateImage({ src: fileURL }), await app.alert("Success!");
} catch (err) {
await app.alert(err.message || err);
}
},
check: async function(app, image) {
return !image.src.startsWith("https://images.amplenote.com");
}
}
},
appOption: {
"Save all images in a tag to Amplenote": {
run: async function(app) {
let tag = await app.prompt(
"Choose the tag. Please note that this plugin is experimental and we don't recommend using it tag-wide without a backup.",
{ inputs: [{
type: "tags"
}] }
);
if (!tag) return;
let notes = await app.filterNotes({ tag });
for (let note of notes)
console.log("Processing note", note.name), await plugin.noteOption["Save all note images to Amplenote"].run(app, note.uuid);
}
}
},
noteOption: {
"Save all note images to Amplenote": {
check: async function(app, noteUUID) {
var _a;
let noteHandle = { uuid: noteUUID }, images = await app.getNoteImages(noteHandle);
return (_a = images == null ? void 0 : images.some((image) => !image.src.startsWith("images.amplenote.com"))) != null ? _a : !1;
},
run: async function(app, noteUUID) {
try {
let noteHandle = { uuid: noteUUID }, images = await app.getNoteImages(noteHandle);
for (let i = 0; i < images.length; i++) {
let image = images[i];
if (console.log(`Processing ${i + 1}/${images.length}: ${image.src}`), image.src.startsWith("images.amplenote.com")) {
console.log(`Skipping already hosted image ${i + 1}/${images.length}`);
continue;
}
let dataURL = await plugin.retry(() => plugin._dataURLFromImageURL(image.src));
if (!dataURL) {
console.warn(`Failed to download image ${i + 1}/${images.length}: ${image.src}`);
continue;
}
let fileURL = await app.attachNoteMedia(noteHandle, dataURL);
await app.updateNoteImage(noteHandle, image, { src: fileURL }), console.log(`Successfully processed ${i + 1}/${images.length}`);
}
} catch (err) {
await app.alert(err.message || err);
}
}
}
},
async _dataURLFromImageURL(src) {
try {
let response = await fetch(src);
if (response.ok) {
let blob = await response.blob();
return await plugin._blobToDataURL(blob);
}
} catch {
console.log("Direct fetch failed, trying proxies...");
}
for (let proxy of plugin.corsProxies)
try {
let proxyUrl = `${proxy}${encodeURIComponent(src)}`, response = await fetch(proxyUrl, {
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
});
if (response.ok) {
let blob = await response.blob();
return await plugin._blobToDataURL(blob);
} else
console.log(`Proxy ${proxy} failed with status:`, response.status);
} catch (e) {
console.log(`Proxy ${proxy} failed with error:`, e.message);
continue;
}
return console.warn(`Failed to fetch image from all available sources: ${src}`), null;
},
async _blobToDataURL(blob) {
return await new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = (event) => resolve(event.target.result), reader.onerror = () => reject(new Error("Failed to read blob as data URL")), reader.readAsDataURL(blob);
});
},
async retry(fn, retries = 2, delayMs = 100) {
for (let i = 0; i < retries; i++)
try {
return await fn();
} catch (e) {
if (console.log(`Attempt ${i + 1} failed:`, e.message), i === retries - 1) throw e;
await plugin.delay(delayMs * (i + 1));
}
},
delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}, plugin_default = plugin;
return plugin;
})()