From f93d609ac39076ce25a64c4fbccad06902a8c41c Mon Sep 17 00:00:00 2001 From: Valerie Date: Sun, 12 Dec 2021 17:09:52 -0500 Subject: [PATCH] properly loading module files --- .gitignore | 4 +- .system | 13 +++++- install.vsh | 5 ++- loader.mjs | 59 +++++++++++++++++++++++++++ package.json | 8 +++- src/externals.d.ts | 7 +++- src/index.ts | 98 +++++++++++++++++++++++++++++++++++---------- src/modules/sshd.ts | 2 +- src/noop.ts | 0 tsconfig.json | 8 ++-- yarn.lock | 42 +++++++++++++++++++ 11 files changed, 212 insertions(+), 34 deletions(-) create mode 100644 loader.mjs create mode 100644 src/noop.ts diff --git a/.gitignore b/.gitignore index 99600f9..18cf523 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules -yarn-error.log \ No newline at end of file +yarn-error.log +.system +dist diff --git a/.system b/.system index 94b61e4..331bc76 100644 --- a/.system +++ b/.system @@ -1,4 +1,13 @@ { - "instances": {}, - "handoff": "" + "handoff": "", + "instances": { + "C4A17A22AD4248858DB47161FE19B2EF": { + "config": {}, + "module": "systemd" + }, + "1B87C6B0E8814F55A7D916848AC3BB36": { + "config": {}, + "module": "sshd" + } + } } \ No newline at end of file diff --git a/install.vsh b/install.vsh index 90ee679..fc59c53 100644 --- a/install.vsh +++ b/install.vsh @@ -1,4 +1,5 @@ create systemd create sshd -systemd add sshd exec sshd start -set handoff invoke systemd boot \ No newline at end of file +invoke systemd add sshd invoke sshd start +set handoff invoke systemd boot +save \ No newline at end of file diff --git a/loader.mjs b/loader.mjs new file mode 100644 index 0000000..1604afa --- /dev/null +++ b/loader.mjs @@ -0,0 +1,59 @@ +import * as tsNode from 'ts-node/esm'; +import * as tsConfigPaths from "tsconfig-paths"; +import chalk from 'chalk'; +import { dirname, resolve as pathResolve } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export const load = tsNode.load; +export const transformSource = tsNode.transformSource; +export const getFormat = tsNode.getFormat; + +let imports = 0; +let echo = true; + +export async function resolve(specifier, context, defaultResolver) { + if(echo === false) { + } else if(imports === 0) { + console.log(chalk.green('#'), chalk.ansi256(242)('@kernel')) + } else { + console.log(chalk.green('#'), chalk.ansi256(242)(specifier)); + } + + if(specifier === '@echo off') { + echo = false; + } + + const maps = { + 'file:///boot': pathResolve(__dirname, 'src', 'index.ts'), + '@kernel:base': pathResolve(__dirname, 'src', 'index.ts'), + '@kernel:log-hook': pathResolve(__dirname, 'src', 'logHook.ts'), + '@commands:executor': pathResolve(__dirname, 'src', 'commands', 'executor.ts'), + '@builtin:systemd': pathResolve(__dirname, 'src', 'modules', 'systemd.ts'), + '@builtin:sshd': pathResolve(__dirname, 'src', 'modules', 'sshd.ts'), + '@echo off': pathResolve(__dirname, 'src', 'noop.ts') + }; + + const matches = Object.keys(maps).filter(map => specifier.startsWith(map)); + + if(matches.length === 1) { + // console.log('matches', matches); + const match = matches[0]; + const replace = maps[match]; + const len = match.length; + specifier = replace + specifier.substring(len) + + } else if(matches.length > 1) { + const error = `Ambiguous import +specifier: ${specifier} matches: +${matches.map(v => ' ' + v).join('\n')}\n`; + throw new Error(error); + } + // if (mappedSpecifier) { + // specifier = `${mappedSpecifier}.js` + // } + const poop = await tsNode.resolve(specifier, context, defaultResolver); + imports ++; + return poop; +} \ No newline at end of file diff --git a/package.json b/package.json index c11bd1a..340005c 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,19 @@ "license": "MIT", "type": "module", "scripts": { - "start": "(clear || cls) && node --loader ts-node/esm ./src/index.ts" + "start": "node --no-warnings --loader ./loader.mjs /boot", + "tsc": "tsc" }, "dependencies": { "@types/node": "^16.11.12", + "@types/uuid": "^8.3.3", "chalk": "^5.0.0", "serverline": "^1.5.0", "ssh2": "^1.5.0", "telnet": "^0.0.1", "ts-node": "^10.4.0", - "typescript": "^4.5.3" + "tsconfig-paths": "^3.12.0", + "typescript": "^4.5.3", + "uuid": "^8.3.2" } } diff --git a/src/externals.d.ts b/src/externals.d.ts index b2ddfc3..a8ebaa8 100644 --- a/src/externals.d.ts +++ b/src/externals.d.ts @@ -1,2 +1,7 @@ declare module "serverline"; -declare module "telnet"; \ No newline at end of file +declare module "telnet"; +declare module "@kernel:base"; +declare module "@commands:executor"; +declare module "@builtin:systemd"; +declare module "@builtin:sshd"; +declare module "@echo off"; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index db6d04f..c291a99 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,19 +1,24 @@ /// -import './logHook.js'; +// console.clear(); + +import '@kernel:log-hook'; +import createExecutor from '@commands:executor'; +import * as uuid from 'uuid'; import serverline from 'serverline'; -import createExecutor from './commands/executor.js'; -import { create } from './commands/create.js'; -import { readFileSync, writeFileSync } from 'fs'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; import { resolve } from 'path' import chalk from 'chalk'; -console.clear(); - const args = process.argv.slice(2); const [ startupFile ] = args; -type Instance = any; +type Instance = { + config: any; + ram: any; + module: string; + functions: any; +}; const system = { instances: new Map(), @@ -28,13 +33,21 @@ export const exec = async (s: string, echo = true) => { serverline.init({ prompt: chalk.cyan('λ ') }); -// serverline.setCompletion(['help', 'command1', 'command2', 'login', 'check', 'ping']) -const executor = createExecutor({ +const kernel = { async create(module: string, name: string) { + // TODO assert module. try { - const functions = await import('./modules/' + module + '.js'); - console.log(functions) + const imported = (await import('@builtin:' + module)); + const functions = 'default' in imported ? imported.default : imported; + const id = name ?? uuid.v4().replace(/-/g, '').toUpperCase(); + system.instances.set(id, { + config: {}, + ram: {}, + module: module, + functions + }); + return id; } catch(e) { console.log(e); e.trace(); @@ -43,19 +56,37 @@ const executor = createExecutor({ quit() { console.log('Shutting down'); serverline.close(); - process.exit(0); + setTimeout(() => process.exit(0), 0); }, ls(flags: any) { if(flags) console.log(flags) - console.log('Instances (' + system.instances.size + ')'); + console.log('Instances', chalk.ansi256(242)('(' + system.instances.size + ')')); for(const [k, v] of system.instances) { - console.log(' ' + k + ':', v); + let colorCode = 0; + for(const char of k) colorCode += char.charCodeAt(0); + colorCode %= 6 ** 3; + colorCode += 16; + console.log( + ' ' + + chalk.ansi256(colorCode)(k.substring(0, 8)) + + ':', JSON.stringify(v.config, null, 2).replace('\n', ' ').trim() + ); } }, save() { const timeStart = new Date().getTime(); - const systemString = JSON.stringify(system, null, 2); + const obj: any = { + handoff: system.handoff, + instances: {} + }; + for(const [id, info] of system.instances.entries()) { + obj.instances[id] = { + config: info.config, + module: info.module + } + } + const systemString = JSON.stringify(obj, null, 2); const fullPath = resolve('.system'); writeFileSync(fullPath, systemString); const elapsed = new Date().getTime() - timeStart; @@ -69,10 +100,20 @@ const executor = createExecutor({ exec: exec, invoke(...a: any[]) { console.log(a); + }, + async script(path: string) { + const fullPath = resolve(path); + const lines = readFileSync(fullPath).toString().split('\n').map(v => v.trim()); + for(const line of lines) { + await exec(line); + } } -}); +}; + +const executor = createExecutor(kernel); serverline.on('line', (a: string) => { + if(a.trim() === "") return; exec(a, false); }) @@ -81,12 +122,25 @@ serverline.on('SIGINT', () => { }); + (async () => { - if(startupFile) { - const fullPath = resolve(startupFile); - const lines = readFileSync(fullPath).toString().split('\n').map(v => v.trim()); - for(const line of lines) { - await exec(line); + + if(existsSync('.system')) { + const state: any = JSON.parse(readFileSync('.system').toString()); + system.handoff = state.handoff; + for(const [id, info] of Object.entries(state.instances)) { + await kernel.create(info.module, id); + system.instances.get(id).config = info.config; } } -})(); \ No newline at end of file + + if(startupFile) { + await exec('script ' + startupFile); + console.log(chalk.green('Script finished, exitting...')); + await exec('quit'); + } +})() + +import '@echo off'; + +serverline.setCompletion(Object.keys(kernel)) \ No newline at end of file diff --git a/src/modules/sshd.ts b/src/modules/sshd.ts index d551f00..9fb61c2 100644 --- a/src/modules/sshd.ts +++ b/src/modules/sshd.ts @@ -1,6 +1,6 @@ import telnet from 'telnet'; -import { exec } from '@kernel'; +import { exec } from '@kernel:base'; export default { start() { diff --git a/src/noop.ts b/src/noop.ts new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json index 875302f..bef4e22 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,9 +5,11 @@ "module": "ESNext", "moduleResolution": "Node", "baseUrl": "./src", - "paths": { - "@kernel": [ "./" ] - } + "outDir": "./dist", + "declaration": true + }, + "paths": { + "@commands:executor": [""] }, "include": [ "src/**/*.ts" diff --git a/yarn.lock b/yarn.lock index b3a7b06..62719cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,11 +34,21 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "@types/node@^16.11.12": version "16.11.12" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10" integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw== +"@types/uuid@^8.3.3": + version "8.3.3" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.3.tgz#c6a60686d953dbd1b1d45e66f4ecdbd5d471b4d0" + integrity sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA== + acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" @@ -117,11 +127,23 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +minimist@^1.2.0: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -153,6 +175,11 @@ ssh2@^1.5.0: cpu-features "0.0.2" nan "^2.15.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + telnet@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/telnet/-/telnet-0.0.1.tgz#db164465c551a99ee785ea7fbba5a67cfc26c4af" @@ -185,6 +212,16 @@ ts-node@^10.4.0: make-error "^1.1.1" yn "3.1.1" +tsconfig-paths@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" + integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + tweetnacl@^0.14.3: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -195,6 +232,11 @@ typescript@^4.5.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c" integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ== +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"