From d958c0111130da3c7090c82a06adbe0c9dbafe12 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Fri, 1 Nov 2024 14:42:42 -0400 Subject: [PATCH] dev: add support for single-file extensions --- mods/mods_available/example-singlefile.js | 7 ++++ src/backend/src/Kernel.js | 51 ++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 mods/mods_available/example-singlefile.js diff --git a/mods/mods_available/example-singlefile.js b/mods/mods_available/example-singlefile.js new file mode 100644 index 00000000..c361c7b1 --- /dev/null +++ b/mods/mods_available/example-singlefile.js @@ -0,0 +1,7 @@ +extension.get('/example-onefile-get', (req, res) => { + res.send('Hello World!'); +}); + +extension.on('install', ({ services }) => { + console.log('install was called'); +}) diff --git a/src/backend/src/Kernel.js b/src/backend/src/Kernel.js index 09ecf309..7a76ca36 100644 --- a/src/backend/src/Kernel.js +++ b/src/backend/src/Kernel.js @@ -215,20 +215,48 @@ class Kernel extends AdvancedBase { async install_extern_mods_ () { const path_ = require('path'); const fs = require('fs'); - + + // In runtime directory, we'll create a `mod_packages` directory.` + if ( fs.existsSync('mod_packages') ) { + fs.rmSync('mod_packages', { recursive: true, force: true }); + } + fs.mkdirSync('mod_packages'); + const mod_install_root_context = Context.get(); const mod_paths = this.environment.mod_paths; for ( const mods_dirpath of mod_paths ) { const mod_dirnames = fs.readdirSync(mods_dirpath); for ( const mod_dirname of mod_dirnames ) { - const mod_path = path_.join(mods_dirpath, mod_dirname); + let mod_path = path_.join(mods_dirpath, mod_dirname); - const stat = fs.statSync(mod_path); - if ( ! stat.isDirectory() ) { + let stat = fs.lstatSync(mod_path); + while ( stat.isSymbolicLink() ) { + mod_path = fs.readlinkSync(mod_path); + stat = fs.lstatSync(mod_path); + } + + if ( ! stat.isDirectory() && !(mod_dirname.endsWith('.js')) ) { continue; } + const mod_name = path_.parse(mod_path).name; + const mod_package_dir = `mod_packages/${mod_name}`; + fs.mkdirSync(mod_package_dir); + + if ( ! stat.isDirectory() ) { + this.create_mod_package_json(mod_package_dir, { + name: mod_name, + }); + fs.copyFileSync(mod_path, path_.join(mod_package_dir, 'main.js')); + } else { + fs.cpSync(mod_path, mod_package_dir, { + recursive: true, + }); + } + + const mod_require_dir = path_.join(process.cwd(), mod_package_dir); + const mod = new ExtensionModule(); mod.extension = new Extension(); @@ -238,7 +266,7 @@ class Kernel extends AdvancedBase { await useapi.aglobalwith({ extension: mod.extension, }, async () => { - const maybe_promise = require(mod_path); + const maybe_promise = require(mod_require_dir); if ( maybe_promise && maybe_promise instanceof Promise ) { await maybe_promise; } @@ -303,6 +331,19 @@ class Kernel extends AdvancedBase { return mod_context; } + + create_mod_package_json (mod_path, { name }) { + const fs = require('fs'); + const path_ = require('path'); + + const data = JSON.stringify({ + name, + version: '1.0.0', + main: 'main.js', + }); + + fs.writeFileSync(path_.join(mod_path, 'package.json'), data); + } } module.exports = { Kernel };