Unzip File via Plugin

as mentioned in this post, I find the idea of a plugin that can render the Open-Raster format quite interesting. I have never dealt with TypeScript before, but wanted to have a look anyway.

The ora format is really just a zip folder with the individual layers in it. But there is also a png in there which has all the layers already merged. So in my brain, all you would have to do is search for an .ora file in the currently open note, unzip it, and display the png in it as usual. If you then click on the file, you open the .ora file normally and end up, for example, in Drawpile and can draw there.

But is it even possible to unzip a file inside a plugin? I have not figured out from the little I have found, can someone possibly give me a hint?

Many greetings


In my Notes Import QNAP plugin I use the node-stream-zip module for this.

const StreamZip = require('node-stream-zip')

		@abstract Unzips a file from zip archive 
	unzip = async function(path: string) : Promise<any>
		var zip = new StreamZip.async({ file: this.archive_path });
		const data = await zip.entryData(path);
		await zip.close();
		return data;		


1 Like

Can you help me further? If I use the module as described here, I get an Error:


ERROR in ./src/index.ts 18:71
    Module parse failed: Octal literal in strict mode (18:71)
    File was processed with these loaders:
     * ./node_modules/ts-loader/index.js
    You may need an additional loader to handle the result of these loaders.
    |             console.info('Plugin started!');
    |             const StreamZip = require('node-stream-zip');
    >             const zip = new StreamZip.async({ file: 'C:\Users\R\Desktop\53htw43.ora' });
    |             function oraFile(noteBody) {
    |                 var beginSearch = noteBody.search(/\.ora]\(\:\//ig);


What exactly does this mean? Do I have to add something to the top of my index.ts?

import joplin from 'api';

	onStart: async function() {
		console.info('Plugin started!');
		const StreamZip = require('node-stream-zip');
		const zip = new StreamZip.async({ file: 'C:\Users\R\Desktop\53htw43.ora' });
		function oraFile(noteBody:string)
			var beginSearch = noteBody.search(/\.ora]\(\:\//ig);
			while (beginSearch != -1)
				var after = noteBody.substring(beginSearch);
				var beginID = after.search(/\//) + beginSearch + 1;
				after = noteBody.substring(beginID);
				var endID = after.search(/\)/) + beginID;
				var fullID = noteBody.substring(beginID, endID);
				return fullID;
		async function updateView() {
			const note = await joplin.workspace.selectedNote();
			if (note) {
					var id = oraFile(note.body);
					console.info('Ressourcen ID: ' + id);
					await zip.extract('mergedimage.png', 'C:\Users\R\Desktop\extracted.png');
					await zip.close();
			} else {
				console.info('No note is selected');
		await joplin.workspace.onNoteSelectionChange(() => {
		await joplin.workspace.onNoteChange(() => {

Thanks already

I assume the reason for the error is your use of the backslash character. It is used to escape characters. So you either make them forward slashes or double them, because \\ means a single backslash in the character string.

For the require function I don't really know: I would place it at the top of the file, just after the import.

Okay, yeah I get that one...replaced the \ with /. Now I get this error...I don't really get an answer on google etc.


    ERROR in ./dist/index.js
    Module not found: Error: Can't resolve 'fs' in 'C:\Users\R\Desktop\Joplin_Plugin\dist'
     @ ./dist/index.js 6:13464-13477
npm ERR! errno 2