impress
Advanced tools
Comparing version 3.0.1 to 3.0.2
@@ -5,7 +5,7 @@ 'use strict'; | ||
const { Procedure } = require('./procedure.js'); | ||
const { Cache } = require('./cache.js'); | ||
const { Place } = require('./place.js'); | ||
class Api extends Cache { | ||
constructor(place, application) { | ||
super(place, application); | ||
class Api extends Place { | ||
constructor(name, application) { | ||
super(name, application); | ||
this.collection = {}; | ||
@@ -12,0 +12,0 @@ this.signatures = {}; |
@@ -7,3 +7,3 @@ 'use strict'; | ||
const { Api } = require('./api.js'); | ||
const { Place } = require('./place.js'); | ||
const { Code } = require('./code.js'); | ||
const { Static } = require('./static.js'); | ||
@@ -38,3 +38,6 @@ const { Cert } = require('./cert.js'); | ||
const { COMMON_CONTEXT } = metarhia.metavm; | ||
const SANDBOX = { ...COMMON_CONTEXT, Error, DomainError, node, npm, metarhia }; | ||
const ERRORS = { Error, DomainError }; | ||
const NAMESPACES = { node, npm, metarhia, process }; | ||
const POLY = { fetch: metarhia.metautil.fetch }; | ||
const SANDBOX = { ...COMMON_CONTEXT, ...ERRORS, ...NAMESPACES, ...POLY }; | ||
@@ -57,6 +60,6 @@ const ERR_INIT = 'Can not initialize an Application'; | ||
this.api = new Api('api', this); | ||
this.lib = new Place('lib', this); | ||
this.db = new Place('db', this); | ||
this.bus = new Place('bus', this); | ||
this.domain = new Place('domain', this); | ||
this.lib = new Code('lib', this); | ||
this.db = new Code('db', this); | ||
this.bus = new Code('bus', this); | ||
this.domain = new Code('domain', this); | ||
@@ -117,5 +120,5 @@ this.starts = []; | ||
this.finalization = true; | ||
await this.stopPlace('domain'); | ||
await this.stopPlace('db'); | ||
await this.stopPlace('lib'); | ||
await this.domain.stop(); | ||
await this.db.stop(); | ||
await this.lib.stop(); | ||
if (this.server) await this.server.close(); | ||
@@ -125,11 +128,2 @@ if (this.logger) await this.logger.close(); | ||
async stopPlace(name) { | ||
if (!this.sandbox) return; | ||
const place = this.sandbox[name]; | ||
for (const moduleName of Object.keys(place)) { | ||
const module = place[moduleName]; | ||
if (typeof module.stop === 'function') await this.execute(module.stop); | ||
} | ||
} | ||
createSandbox() { | ||
@@ -142,3 +136,3 @@ const { config, console, resources, schemas } = this; | ||
const application = new UserApplication(this, userAppData); | ||
const sandbox = { ...SANDBOX, console, application, config, process }; | ||
const sandbox = { ...SANDBOX, console, application, config }; | ||
sandbox.api = {}; | ||
@@ -145,0 +139,0 @@ sandbox.lib = this.lib.tree; |
@@ -7,4 +7,4 @@ 'use strict'; | ||
class Cert extends Static { | ||
constructor(place, application, options = {}) { | ||
super(place, application, options); | ||
constructor(name, application, options = {}) { | ||
super(name, application, options); | ||
this.domains = new Map(); | ||
@@ -11,0 +11,0 @@ } |
'use strict'; | ||
const CWD = process.cwd(); | ||
const wt = require('node:worker_threads'); | ||
const { createRequire } = require('node:module'); | ||
const metautil = require('metautil'); | ||
const appRequire = createRequire(`file://${CWD}/server.js`); | ||
@@ -23,3 +27,3 @@ const node = {}; | ||
const npmpkg = ['ws']; | ||
const pkg = require(process.cwd() + '/package.json'); | ||
const pkg = require(CWD + '/package.json'); | ||
if (pkg.dependencies) npmpkg.push(...Object.keys(pkg.dependencies)); | ||
@@ -48,3 +52,3 @@ const dependencies = [...internals, ...npmpkg, ...metapkg]; | ||
try { | ||
lib = internals.includes(name) ? require(`node:${name}`) : require(name); | ||
lib = internals.includes(name) ? require(`node:${name}`) : appRequire(name); | ||
} catch { | ||
@@ -51,0 +55,0 @@ if (npmpkg.includes(name) || !optional.includes(name)) { |
'use strict'; | ||
const { metarhia } = require('./deps.js'); | ||
const { Cache } = require('./cache.js'); | ||
const bus = require('./bus.js'); | ||
const { node, metarhia } = require('./deps.js'); | ||
class Place extends Cache { | ||
constructor(place, application) { | ||
super(place, application); | ||
this.tree = {}; | ||
class Place { | ||
constructor(name, application) { | ||
this.name = name; | ||
this.path = application.absolute(name); | ||
this.application = application; | ||
} | ||
stop(name, method) { | ||
const timeout = this.application.config.server.timeouts.watch; | ||
setTimeout(() => { | ||
if (this.tree[name] !== undefined) return; | ||
this.application.execute(method); | ||
}, timeout); | ||
} | ||
set(relPath, unit) { | ||
const names = metarhia.metautil.parsePath(relPath); | ||
let level = this.tree; | ||
const last = names.length - 1; | ||
for (let depth = 0; depth <= last; depth++) { | ||
const name = names[depth]; | ||
let next = level[name]; | ||
if (depth === last) { | ||
if (unit === null) { | ||
if (name === 'stop') this.stop(names[0], level.stop); | ||
delete level[name]; | ||
return; | ||
} | ||
next = unit; | ||
unit.parent = level; | ||
async load(targetPath = this.path) { | ||
await metarhia.metautil.ensureDirectory(this.path); | ||
this.application.watcher.watch(targetPath); | ||
try { | ||
const files = await node.fsp.readdir(targetPath, { withFileTypes: true }); | ||
for (const file of files) { | ||
const { name } = file; | ||
if (name.startsWith('.eslint')) continue; | ||
const filePath = node.path.join(targetPath, name); | ||
if (file.isDirectory()) await this.load(filePath); | ||
else await this.change(filePath); | ||
} | ||
if (next === undefined) next = { parent: level }; | ||
level[name] = next; | ||
if (depth === 1 && name === 'start') { | ||
if (unit.constructor.name === 'AsyncFunction') { | ||
this.application.starts.push(unit); | ||
} else { | ||
const msg = `${relPath} expected to be async function`; | ||
this.application.console.error(msg); | ||
} | ||
} | ||
level = next; | ||
} | ||
} | ||
delete(filePath) { | ||
const relPath = filePath.substring(this.path.length + 1); | ||
this.set(relPath, null); | ||
} | ||
async change(filePath) { | ||
if (!filePath.endsWith('.js')) return; | ||
const { application, path, place } = this; | ||
const options = { context: application.sandbox, filename: filePath }; | ||
try { | ||
const { exports } = await metarhia.metavm.readScript(filePath, options); | ||
const relPath = filePath.substring(path.length + 1); | ||
const exp = place === 'bus' ? bus.prepare(exports, application) : exports; | ||
this.set(relPath, exp); | ||
} catch (error) { | ||
if (error.code !== 'ENOENT') { | ||
application.console.error(error.stack); | ||
} | ||
const console = this.application.console || global.console; | ||
console.error(error.stack); | ||
} | ||
@@ -70,0 +28,0 @@ } |
@@ -19,2 +19,3 @@ 'use strict'; | ||
async init() { | ||
await metarhia.metautil.ensureDirectory(this.path); | ||
const now = metarhia.metautil.nowDate(); | ||
@@ -21,0 +22,0 @@ try { |
'use strict'; | ||
const { node, metarhia } = require('./deps.js'); | ||
const { Cache } = require('./cache.js'); | ||
const { Place } = require('./place.js'); | ||
class Schemas extends Cache { | ||
constructor(place, application) { | ||
super(place, application); | ||
class Schemas extends Place { | ||
constructor(name, application) { | ||
super(name, application); | ||
this.model = null; | ||
@@ -10,0 +10,0 @@ } |
'use strict'; | ||
const { node, metarhia } = require('./deps.js'); | ||
const { Cache } = require('./cache.js'); | ||
const { Place } = require('./place.js'); | ||
@@ -9,5 +9,5 @@ const WIN = process.platform === 'win32'; | ||
class Static extends Cache { | ||
constructor(place, application, options = {}) { | ||
super(place, application); | ||
class Static extends Place { | ||
constructor(name, application, options = {}) { | ||
super(name, application); | ||
this.files = new Map(); | ||
@@ -14,0 +14,0 @@ this.ext = options.ext; |
{ | ||
"name": "impress", | ||
"version": "3.0.1", | ||
"version": "3.0.2", | ||
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>", | ||
@@ -70,12 +70,12 @@ "description": "Enterprise application server for Node.js", | ||
"metautil": "^3.11.0", | ||
"metavm": "^1.2.4", | ||
"metavm": "^1.2.6", | ||
"metawatch": "^1.1.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.4.4", | ||
"@types/node": "^20.4.5", | ||
"@types/ws": "^8.5.5", | ||
"eslint": "^8.45.0", | ||
"eslint": "^8.46.0", | ||
"eslint-config-metarhia": "^8.2.1", | ||
"eslint-config-prettier": "^8.7.0", | ||
"eslint-plugin-import": "^2.27.5", | ||
"eslint-config-prettier": "^8.9.0", | ||
"eslint-plugin-import": "^2.28.0", | ||
"eslint-plugin-prettier": "^5.0.0", | ||
@@ -82,0 +82,0 @@ "metatests": "^0.8.2", |
@@ -21,6 +21,10 @@ import { EventEmitter } from 'node:events'; | ||
export interface Cache { | ||
export interface Static { | ||
get(name: string): unknown; | ||
} | ||
export interface Schemas { | ||
get(name: string): unknown; | ||
} | ||
export interface Listener { | ||
@@ -33,4 +37,4 @@ (...args: Array<unknown>): void; | ||
server: { host: string; port: number; protocol: string }; | ||
resources: Cache; | ||
schemas: Cache; | ||
resources: Static; | ||
schemas: Schemas; | ||
scheduler: Scheduler; | ||
@@ -37,0 +41,0 @@ introspect: () => Promise<object>; |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
63738
1667
4
Updatedmetavm@^1.2.6