feat: add bounded binary file writes
This commit is contained in:
@@ -288,6 +288,12 @@ export function createPluginAPI(pluginId) {
|
||||
return App.WriteVaultTextFile(pluginId, relativePath, String(content == null ? '' : content), options || {});
|
||||
});
|
||||
},
|
||||
writeBytes: function(relativePath, dataBase64, options) {
|
||||
assertActive('files.writeBytes(' + relativePath + ')');
|
||||
return callBackendErrorString(pluginId, 'files.writeBytes(' + relativePath + ')', function() {
|
||||
return App.WriteVaultFileBytes(pluginId, relativePath, String(dataBase64 == null ? '' : dataBase64), options || {});
|
||||
});
|
||||
},
|
||||
createFolder: function(relativePath) {
|
||||
assertActive('files.createFolder(' + relativePath + ')');
|
||||
return callBackendErrorString(pluginId, 'files.createFolder(' + relativePath + ')', function() {
|
||||
|
||||
@@ -1327,6 +1327,22 @@
|
||||
vaultFiles[norm.path] = { type: 'file', content: String(content == null ? '' : content), modifiedAt: new Date().toISOString() };
|
||||
return Promise.resolve('');
|
||||
},
|
||||
WriteVaultFileBytes: function (pluginId, relativePath, dataBase64, options) {
|
||||
var err = requirePluginPermission(pluginId, 'files.write');
|
||||
if (err) return Promise.resolve(err);
|
||||
var norm = normalizeVaultPath(relativePath, false);
|
||||
if (norm.error) return Promise.resolve(norm.error);
|
||||
options = options || {};
|
||||
var existing = vaultFiles[norm.path];
|
||||
if (existing && existing.type !== 'file') return Promise.resolve('not-regular-file: ' + norm.path);
|
||||
if (existing && !options.overwrite) return Promise.resolve('conflict: ' + norm.path);
|
||||
if (!existing && !options.createIfMissing) return Promise.resolve('not-found: ' + norm.path);
|
||||
var parent = parentPath(norm.path);
|
||||
if (!vaultFiles[parent] || vaultFiles[parent].type !== 'folder') return Promise.resolve('parent-not-found: ' + parent);
|
||||
var content = typeof atob === 'function' ? atob(String(dataBase64 || '')) : '';
|
||||
vaultFiles[norm.path] = { type: 'file', content: content, modifiedAt: new Date().toISOString() };
|
||||
return Promise.resolve('');
|
||||
},
|
||||
CreateVaultFolder: function (pluginId, relativePath) {
|
||||
var err = requirePluginPermission(pluginId, 'files.write');
|
||||
if (err) return Promise.resolve(err);
|
||||
|
||||
@@ -19,6 +19,10 @@ globalThis.window = {
|
||||
calls.push({ method: 'RestoreVaultTrash', pluginId, trashId, options });
|
||||
return Promise.resolve(['Docs/restored.txt', '']);
|
||||
},
|
||||
WriteVaultFileBytes: (pluginId, relativePath, dataBase64, options) => {
|
||||
calls.push({ method: 'WriteVaultFileBytes', pluginId, relativePath, dataBase64, options });
|
||||
return Promise.resolve('');
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -40,20 +44,28 @@ if (!api.files || typeof api.files.restoreTrash !== 'function') {
|
||||
if (typeof api.files.readBytes !== 'function') {
|
||||
throw new Error('api.files.readBytes is missing');
|
||||
}
|
||||
if (typeof api.files.writeBytes !== 'function') {
|
||||
throw new Error('api.files.writeBytes is missing');
|
||||
}
|
||||
|
||||
const bytes = await api.files.readBytes('Docs/image.png');
|
||||
if (bytes.dataBase64 !== 'iVBORw==' || bytes.mimeHint !== 'image/png') {
|
||||
throw new Error(`unexpected readBytes result: ${JSON.stringify(bytes)}`);
|
||||
}
|
||||
|
||||
await api.files.writeBytes('Docs/copy.png', 'iVBORw==', { createIfMissing: true });
|
||||
|
||||
const restored = await api.files.restoreTrash('trash-1', { overwrite: true });
|
||||
if (restored !== 'Docs/restored.txt') {
|
||||
throw new Error(`unexpected restore result: ${JSON.stringify(restored)}`);
|
||||
}
|
||||
if (calls.length !== 2 || calls[0].method !== 'ReadVaultFileBytes' || calls[0].pluginId !== 'verstak.files' || calls[0].relativePath !== 'Docs/image.png') {
|
||||
if (calls.length !== 3 || calls[0].method !== 'ReadVaultFileBytes' || calls[0].pluginId !== 'verstak.files' || calls[0].relativePath !== 'Docs/image.png') {
|
||||
throw new Error(`unexpected ReadVaultFileBytes call: ${JSON.stringify(calls)}`);
|
||||
}
|
||||
if (calls[1].method !== 'RestoreVaultTrash' || calls[1].pluginId !== 'verstak.files' || calls[1].trashId !== 'trash-1' || calls[1].options.overwrite !== true) {
|
||||
if (calls[1].method !== 'WriteVaultFileBytes' || calls[1].pluginId !== 'verstak.files' || calls[1].relativePath !== 'Docs/copy.png' || calls[1].dataBase64 !== 'iVBORw==' || calls[1].options.createIfMissing !== true) {
|
||||
throw new Error(`unexpected WriteVaultFileBytes call: ${JSON.stringify(calls)}`);
|
||||
}
|
||||
if (calls[2].method !== 'RestoreVaultTrash' || calls[2].pluginId !== 'verstak.files' || calls[2].trashId !== 'trash-1' || calls[2].options.overwrite !== true) {
|
||||
throw new Error(`unexpected RestoreVaultTrash call: ${JSON.stringify(calls)}`);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
@@ -149,3 +149,5 @@ export function WritePluginSetting(arg1:string,arg2:string,arg3:any):Promise<str
|
||||
export function WritePluginSettings(arg1:string,arg2:Record<string, any>):Promise<string>;
|
||||
|
||||
export function WriteVaultTextFile(arg1:string,arg2:string,arg3:string,arg4:files.WriteOptions):Promise<string>;
|
||||
|
||||
export function WriteVaultFileBytes(arg1:string,arg2:string,arg3:string,arg4:files.WriteOptions):Promise<string>;
|
||||
|
||||
@@ -285,3 +285,7 @@ export function WritePluginSettings(arg1, arg2) {
|
||||
export function WriteVaultTextFile(arg1, arg2, arg3, arg4) {
|
||||
return window['go']['api']['App']['WriteVaultTextFile'](arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
export function WriteVaultFileBytes(arg1, arg2, arg3, arg4) {
|
||||
return window['go']['api']['App']['WriteVaultFileBytes'](arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user