feat: add download file method for files generated by plugin
This commit is contained in:
committed by
Linus Rath
parent
a08a9e9ed3
commit
a679d82cc3
@@ -60,6 +60,7 @@ const PERM_PER_METHOD: Record<string, Permission | null> = {
|
|||||||
'ui.prompt': null,
|
'ui.prompt': null,
|
||||||
'ui.rerenderEmail': null,
|
'ui.rerenderEmail': null,
|
||||||
'ui.openExternalUrl': null,
|
'ui.openExternalUrl': null,
|
||||||
|
'ui.downloadFile': 'ui:download-file'
|
||||||
};
|
};
|
||||||
|
|
||||||
function hasPermission(plugin: InstalledPlugin, perm: Permission): boolean {
|
function hasPermission(plugin: InstalledPlugin, perm: Permission): boolean {
|
||||||
@@ -400,6 +401,24 @@ async function saveFile(formerFileID:string, file: File): Promise<string> {
|
|||||||
return fileId;
|
return fileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Download files generated by the plugin. This is not user's files or attachments ──────────────────────────
|
||||||
|
async function downloadFile(args: { content: string; filename: string; contentType?: string }): Promise<void> {
|
||||||
|
const { content, filename, contentType = 'application/json' } = args;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = URL.createObjectURL(new Blob([content], { type: contentType }));
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = filename;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Failed to download file: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── admin config (same as before) ────────────────────────────
|
// ─── admin config (same as before) ────────────────────────────
|
||||||
|
|
||||||
async function adminGetAll(pluginId: string): Promise<Record<string, unknown>> {
|
async function adminGetAll(pluginId: string): Promise<Record<string, unknown>> {
|
||||||
@@ -547,6 +566,10 @@ export async function dispatchApiCall(
|
|||||||
window.open(parsed.toString(), '_blank', 'noopener,noreferrer');
|
window.open(parsed.toString(), '_blank', 'noopener,noreferrer');
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
case 'ui.downloadFile': {
|
||||||
|
const opts = args[0] as { content: string; filename: string; contentType?: string };
|
||||||
|
return downloadFile(opts);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled method "${method}"`);
|
throw new Error(`Unhandled method "${method}"`);
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ export const API_METHODS = [
|
|||||||
'jmap.fetchBlob', 'jmap.sendRaw',
|
'jmap.fetchBlob', 'jmap.sendRaw',
|
||||||
'admin.getConfig', 'admin.getAllConfig', 'admin.setConfig', 'admin.deleteConfig',
|
'admin.getConfig', 'admin.getAllConfig', 'admin.setConfig', 'admin.deleteConfig',
|
||||||
'toast.success', 'toast.error', 'toast.info', 'toast.warning',
|
'toast.success', 'toast.error', 'toast.info', 'toast.warning',
|
||||||
'ui.confirm', 'ui.alert', 'ui.prompt', 'ui.rerenderEmail', 'ui.openExternalUrl',
|
'ui.confirm', 'ui.alert', 'ui.prompt', 'ui.rerenderEmail', 'ui.openExternalUrl', 'ui.downloadFile'
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type ApiMethod = (typeof API_METHODS)[number];
|
export type ApiMethod = (typeof API_METHODS)[number];
|
||||||
|
|||||||
@@ -232,6 +232,9 @@ function buildPluginApi(manifest: PluginManifest) {
|
|||||||
/** Opens an http/https URL in a new tab via host `window.open`. */
|
/** Opens an http/https URL in a new tab via host `window.open`. */
|
||||||
openExternalUrl: (url: string, target?: string) =>
|
openExternalUrl: (url: string, target?: string) =>
|
||||||
callApi('ui.openExternalUrl', [url, target]) as Promise<void>,
|
callApi('ui.openExternalUrl', [url, target]) as Promise<void>,
|
||||||
|
/** Downloads a file generated by the plugin. Not a user's file or attachment. */
|
||||||
|
downloadFile: (opts: { content: string; filename: string; contentType?: string }) =>
|
||||||
|
callApi('ui.downloadFile', [opts]) as Promise<void>,
|
||||||
},
|
},
|
||||||
admin: {
|
admin: {
|
||||||
getConfig: (key: string) => callApi('admin.getConfig', [key]),
|
getConfig: (key: string) => callApi('admin.getConfig', [key]),
|
||||||
|
|||||||
@@ -925,6 +925,7 @@ export const ALL_PERMISSIONS = [
|
|||||||
'http:post', 'http:fetch',
|
'http:post', 'http:fetch',
|
||||||
'ui:observe', 'ui:toolbar', 'ui:app-top-banner', 'ui:email-banner', 'ui:email-footer',
|
'ui:observe', 'ui:toolbar', 'ui:app-top-banner', 'ui:email-banner', 'ui:email-footer',
|
||||||
'ui:email-details',
|
'ui:email-details',
|
||||||
|
'ui:download-file',
|
||||||
'ui:composer-toolbar', 'ui:composer-sidebar',
|
'ui:composer-toolbar', 'ui:composer-sidebar',
|
||||||
'ui:sidebar-widget', 'ui:settings-section',
|
'ui:sidebar-widget', 'ui:settings-section',
|
||||||
'ui:context-menu', 'ui:navigation-rail', 'ui:keyboard',
|
'ui:context-menu', 'ui:navigation-rail', 'ui:keyboard',
|
||||||
|
|||||||
Reference in New Issue
Block a user