Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

low

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

low - npm Package Compare versions

Comparing version 1.1.91 to 1.1.92

22

js-doer-tests/basic.js
/** @module Basic **/
const Jest = require('jest');
exports = {
Basic: {
/** @type {import('../src').JSModuleFunction} **/
async main(env, context, parameters) {
const test1 = 'TEST';
const test2 = `<div id="TEST"></div>`;
module.exports = {
/** @type {import('../src').JSModuleFunction} **/
async main(env, context, modules, parameters) {
const test1 = Jest.getVersion();
const [test2, second] = await modules.Other.getMethod()(env, context, modules, parameters);
const test3 = /*html*/`<div id="${test1}"></div>`;
return [test1, test2, test3, second];
},
/** @type {import('../src').JSModuleFunction} **/
async second(env, context, modules, parameters) {
return 'SECOND'
return [test1, test2];
}
}
}

@@ -1,47 +0,14 @@

/// <reference types="node" />
import Module from 'module';
import { Doer } from './doer';
import { ConnectorContext } from '../connectors/connector';
import { TaskConfig } from '../environment';
import { Environment, IMap } from '..';
export declare class JSDoer<C, S> extends Doer<any, IMap<string>> {
modules: IMap<JSModule>;
moduleErrors: IMap<any>;
import { ConnectorContext, Environment } from '..';
export declare class JSDoer extends Doer<JSDoerConfig, any> {
moduleContext: any;
module: any;
modules: any;
setup(): Promise<void>;
hasModule: (name: string) => boolean;
getOrSetModule(name: string, code?: string): JSModule;
main(context: ConnectorContext<any>, taskConfig: TaskConfig, config: JSTask): Promise<any>;
getModule: <T>(modules: any, moduleName: string) => T;
executeDoer: <T>(env: Environment, doerName: string, context: ConnectorContext<any>, coreConfig: T, runAsTask?: boolean, metadata?: any) => Promise<any>;
loadCode(code: any): Promise<void>;
main(context: any, taskConfig: any, config: any): Promise<any>;
}
export declare class JSModule {
private _errors;
private _path;
private _code;
private _name?;
private _module?;
get errors(): IMap<Error>;
get path(): string;
get code(): string;
get exports(): any;
get main(): any;
get setup(): any;
get hasErrors(): boolean;
constructor(path: string, code: string);
get module(): Module | undefined;
get name(): string;
getMethod(name?: string): any;
export declare type JSModuleFunction = (env: Environment, context: ConnectorContext<any>, parameters: any) => Promise<any>;
export interface JSDoerConfig {
code: string;
}
export declare type JSModuleFunction = (env: Environment, context: ConnectorContext<any>, modules: IMap<JSModule>, parameters: any, utilities: JSModuleUtilities) => Promise<any>;
export interface JSModuleUtilities {
getModule: <T>(modules: any, moduleName: string) => any & {
main?: JSModuleFunction;
};
executeDoer: <T>(env: Environment, doerName: string, context: ConnectorContext<any>, coreConfig: T, runAsTask?: boolean, metadata?: any) => Promise<any>;
}
export interface JSTask {
module: string;
code?: string;
parameters: IMap<any>;
method?: string;
}

@@ -14,67 +14,61 @@ "use strict";

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const module_1 = __importDefault(require("module"));
// import Module from 'module';
// import Url from 'url';
const vm_1 = __importDefault(require("vm"));
const doer_1 = require("./doer");
const utilities_1 = require("../utilities");
class JSDoer extends doer_1.Doer {
constructor() {
super(...arguments);
this.modules = {};
this.moduleErrors = {};
this.hasModule = (name) => !!this.modules[name];
this.getModule = (modules, moduleName) => {
const module = modules[moduleName];
if (!module)
throw new Error(`No JSModule with the name '${moduleName}' has been loaded`);
return module.exports;
};
this.executeDoer = (env, doerName, context, coreConfig, runAsTask = false, metadata = {}) => __awaiter(this, void 0, void 0, function* () {
const doer = env.getDoer(doerName);
const config = { name: `JSModule`, doer: doerName, config: coreConfig, metadata };
if (runAsTask) {
return yield doer.execute(context, config);
}
else {
return yield doer.main(context, config, coreConfig);
}
setup() {
return __awaiter(this, void 0, void 0, function* () {
const code = typeof this.config.code === 'string' ? this.config.code : '';
yield this.loadCode(code);
});
}
setup() {
loadCode(code) {
return __awaiter(this, void 0, void 0, function* () {
const errors = [];
for (const [name, code] of Object.entries(this.config)) {
const newModule = new JSModule(name, code);
if (newModule.setup)
yield newModule.setup();
this.modules[newModule.name] = newModule;
if (newModule.hasErrors)
errors.push(newModule);
}
if (errors.length > 0) {
console.error(`The following ${errors.length} JSDoer modules have errors: ${errors.map(error => error.name).join(', ')}`);
}
this.moduleContext = vm_1.default.createContext({
require: (filename) => {
const module = require(filename);
return module;
},
exports: {}
});
this.module = new vm_1.default.SourceTextModule(code, {
context: this.moduleContext,
initializeImportMeta(meta) {
meta.url = __dirname;
}
});
yield this.module.link((specifier, referencingModule) => __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const module = yield Promise.resolve().then(() => __importStar(require(specifier)));
const exportNames = Object.keys(module);
const syntheticModule = new vm_1.default.SyntheticModule(exportNames, function () {
exportNames.forEach(key => {
this.setExport(key, module[key]);
});
}, { context: this.moduleContext });
resolve(syntheticModule);
}));
}));
yield this.module.evaluate();
this.modules = this.moduleContext.exports;
});
}
getOrSetModule(name, code) {
if (this.hasModule(name))
return this.modules[name];
if (code) {
const newModule = new JSModule(name, code);
this.modules[newModule.name] = newModule;
return this.modules[newModule.name];
}
throw new Error(`A module with the name '${name}' has not been registered`);
}
main(context, taskConfig, config) {
return __awaiter(this, void 0, void 0, function* () {
try {
const module = this.getOrSetModule(config.module, config.code);
const method = module.getMethod(config.method);
const output = yield method(this.env, context, this.modules, config.parameters, {
getModule: this.getModule, executeDoer: this.executeDoer
});
const module = this.modules[config.module];
const method = module[config.method || 'main'];
const output = yield method(this.env, context, config.parameters);
return output;
}
catch (err) {
this.moduleErrors[config.module || 'unknown'] = err;
throw err;

@@ -86,70 +80,2 @@ }

exports.JSDoer = JSDoer;
class JSModule {
constructor(path, code) {
this._errors = {};
this._path = path;
this._code = code;
}
get errors() { return this._errors; }
get path() { return this._path; }
get code() { return this._code; }
get exports() {
return (this.module ?
this.module.exports :
{});
}
get main() {
return (!this.module ?
null :
typeof this.module.exports === 'function' ?
this.module.exports :
typeof this.module.exports.main === 'function' ?
this.module.exports.main :
null);
}
get setup() {
return (!this.module ?
null :
utilities_1.isObject(this.module.exports) && typeof this.module.exports.setup === 'function' ?
this.module.exports.setup :
null);
}
get hasErrors() { return Object.keys(this._errors).length > 0; }
get module() {
if (!this._module) {
try {
this._module = new module_1.default('');
this._module.paths = require.main.paths;
this._module.path = this.path;
this._module._compile(this.code, this.path);
}
catch (err) {
this._errors.module = err;
}
}
return this._module;
}
get name() {
if (!this._name) {
try {
const found = this.code.match(/(?:\@module\s+)([\w]+)/);
this._name = (found && found[1] ||
this.path.split('/').slice(-1)[0].split('.')[0] ||
this.path);
}
catch (err) {
this._errors.name = err;
}
}
return this._name || this.path;
}
getMethod(name = 'main') {
if (name === 'main' && this.main)
return this.main;
if (typeof this.exports[name] === 'function')
return this.exports[name];
throw Error(`No such method as '${name}' on module '${this.name}'`);
}
}
exports.JSModule = JSModule;
//# sourceMappingURL=js-doer.js.map

@@ -5,3 +5,3 @@ export * from './cache-managers/cache-manager';

export * from './doers/doer';
export * from './doers/js-doer';
export * from './doers/js-doer.js';
export * from './doers/multi-doer';

@@ -8,0 +8,0 @@ export * from './environment';

@@ -10,3 +10,3 @@ "use strict";

__export(require("./doers/doer"));
__export(require("./doers/js-doer"));
__export(require("./doers/js-doer.js"));
__export(require("./doers/multi-doer"));

@@ -13,0 +13,0 @@ __export(require("./environment"));

{
"name": "low",
"version": "1.1.91",
"version": "1.1.92",
"description": "a templating driven low-code framework for rapid systems development",

@@ -14,3 +14,3 @@ "main": "lib/index.js",

"clean": "rm -rf docs/; rm -rf lib/; rm -rf coverage/",
"test": "jest --coverage",
"test": "node --experimental-vm-modules ./node_modules/.bin/jest --coverage",
"build": "npm run clean && tsc && npm test"

@@ -26,4 +26,5 @@ },

},
"gitHead": "7541785386fb6c0a69b171870635f52a469ba1ac",
"gitHead": "11f8f1efb302e520ff0145a8af367d8f0096cf5e",
"devDependencies": {
"@babel/code-frame": "^7.21.4",
"@types/jest": "^24.9.0",

@@ -30,0 +31,0 @@ "jest": "^24.9.0",

import { Environment } from '../environment';
import { ConnectorContext } from '../connectors/connector';
import { JSDoer } from '../doers/js-doer';
import { IMap } from '..';
import { JSDoer } from './js-doer';
import FS from 'fs';

@@ -13,29 +12,25 @@ import Path from 'path';

const context = createEmptyContext(env);
console.log(`\n\nDOER:\n${JSON.stringify(doer.main, null, 2)}`);
const [test1, test2] = await doer.modules.Basic.main(env, context, {});
const basicModule = doer.modules.Basic;
const [test1, test2, test3, test4] = await basicModule.getMethod()(env, context, doer.modules, {}, {});
expect(test1).toEqual('24.9.0');
expect(test2).toEqual('24.9.0');
expect(test3).toEqual('<div id="24.9.0"></div>');
expect(test4).toEqual('SECOND');
expect(test1).toEqual('TEST');
expect(test2).toEqual(`<div id="TEST"></div>`);
});
function getTestModulesConfig () {
const config: IMap<string> = {};
const testModulesPath = Path.join(__dirname, '..', '..', 'js-doer-tests');
const modules = FS.readdirSync(testModulesPath);
for (const filename of modules) {
const path = Path.join(testModulesPath, filename);
const code = FS.readFileSync(path).toString();
config[path] = code;
}
return config;
const testModulePath = Path.join(__dirname, '..', '..', 'js-doer-tests', 'basic.js');
console.log(`\n\nLOADING TEST CODE FROM '${testModulePath}`);
const module = { code: FS.readFileSync(testModulePath).toString() };
console.log(`\n\nCODE:\n${module.code}`);
return module;
}
async function setupEnvironment(): Promise<[JSDoer<any, IMap<string>>, Environment]> {
async function setupEnvironment(): Promise<[JSDoer, Environment]> {
const doer = new JSDoer();
const modules = { doers: [doer] };
const config = { modules: { JSDoer: getTestModulesConfig() } };
console.log(`\n\nJSDOER TEST ENV CONFIG:\n${JSON.stringify(config)}`);
const env = new Environment(modules, [], config);
console.log(`\n\nJSDOER ENV MODULE:\n${JSON.stringify(env.config)}`)
await env.init();

@@ -42,0 +37,0 @@ return [doer, env];

@@ -1,169 +0,79 @@

import Module from 'module';
// import Module from 'module';
// import Url from 'url';
import VM from 'vm';
import { Doer } from './doer';
import { ConnectorContext } from '../connectors/connector';
import { TaskConfig } from '../environment';
import { Environment, IMap } from '..';
import { isObject } from '../utilities';
import { ConnectorContext, Environment } from '..';
export class JSDoer extends Doer<JSDoerConfig, any> {
moduleContext: any;
module: any;
modules: any;
export class JSDoer<C, S> extends Doer<any, IMap<string>> {
modules: IMap<JSModule> = {};
moduleErrors: IMap<any> = {};
async setup() {
const errors = [];
const code = typeof this.config.code === 'string' ? this.config.code : '';
await this.loadCode(code);
}
for (const [name, code] of Object.entries(this.config)) {
const newModule = new JSModule(name, code as string);
if (newModule.setup) await newModule.setup();
this.modules[newModule.name] = newModule;
if (newModule.hasErrors) errors.push(newModule);
}
async loadCode (code) {
this.moduleContext = VM.createContext({
require: (filename) => {
const module = require(filename);
return module;
},
exports: {}
});
if (errors.length > 0) {
console.error(`The following ${errors.length} JSDoer modules have errors: ${errors.map(error => error.name).join(', ')}`);
}
}
this.module = new (VM as any).SourceTextModule(code, {
context: this.moduleContext,
initializeImportMeta(meta) {
meta.url = __dirname
}
});
hasModule = (name: string) => !!this.modules[name];
await this.module.link(async (specifier, referencingModule) => {
return new Promise(async (resolve, reject) => {
const module = await import(specifier);
const exportNames = Object.keys(module);
getOrSetModule(name: string, code?: string) {
if (this.hasModule(name)) return this.modules[name];
if (code) {
const newModule = new JSModule(name, code);
this.modules[newModule.name] = newModule
return this.modules[newModule.name];
}
throw new Error(`A module with the name '${name}' has not been registered`);
const syntheticModule = new (VM as any).SyntheticModule(
exportNames,
function () {
exportNames.forEach(key => {
(this as any).setExport(key, module[key]);
});
}, { context: this.moduleContext }
);
resolve(syntheticModule);
});
});
await this.module.evaluate();
this.modules = this.moduleContext.exports;
}
async main(context: ConnectorContext<any>, taskConfig: TaskConfig, config: JSTask): Promise<any> {
async main(context, taskConfig, config) {
try {
const module = this.getOrSetModule(config.module, config.code);
const method = module.getMethod(config.method);
const output = await method(this.env, context, this.modules, config.parameters, {
getModule: this.getModule, executeDoer: this.executeDoer
});
const module = this.modules[config.module];
const method = module[config.method || 'main'];
const output = await method(this.env, context, config.parameters);
return output;
} catch (err) {
this.moduleErrors[config.module || 'unknown'] = err;
throw err;
}
}
getModule = <T>(modules: any, moduleName: string) => {
const module = modules[moduleName];
if (!module) throw new Error(`No JSModule with the name '${moduleName}' has been loaded`);
return module.exports as T;
}
executeDoer = async <T>(env: Environment, doerName: string, context: ConnectorContext<any>, coreConfig: T, runAsTask = false, metadata: any = {}) => {
const doer = env.getDoer(doerName);
const config = { name: `JSModule`, doer: doerName, config: coreConfig, metadata };
if (runAsTask) {
return await doer.execute(context, config as TaskConfig);
} else {
return await doer.main(context, config as TaskConfig, coreConfig);
}
}
}
export class JSModule {
private _errors: IMap<Error> = {};
private _path: string;
private _code: string;
private _name?: string;
private _module?: Module;
export type JSModuleFunction = (env: Environment, context: ConnectorContext<any>, parameters: any) => Promise<any>;
get errors() { return this._errors; }
get path() { return this._path; }
get code() { return this._code; }
// export interface JSTask {
// module: string;
// code?: string;
// parameters: IMap<any>;
// method?: string;
// }
get exports() {
return (
this.module ?
this.module.exports :
{}
);
}
get main() {
return (
!this.module ?
null :
typeof this.module.exports === 'function' ?
this.module.exports :
typeof this.module.exports.main === 'function' ?
this.module.exports.main :
null
);
}
get setup() {
return (
!this.module ?
null :
isObject(this.module.exports) && typeof this.module.exports.setup === 'function' ?
this.module.exports.setup :
null
);
}
get hasErrors() { return Object.keys(this._errors).length > 0; }
constructor(path: string, code: string) {
this._path = path;
this._code = code;
}
get module() {
if (!this._module) {
try {
this._module = new Module('');
this._module.paths = (require as any).main.paths;
(this._module as any).path = this.path;
(this._module as any)._compile(this.code, this.path);
} catch (err) {
this._errors.module = err as Error;
}
}
return this._module;
}
get name() {
if (!this._name) {
try {
const found = this.code.match(/(?:\@module\s+)([\w]+)/);
this._name = (
found && found[1] ||
this.path.split('/').slice(-1)[0].split('.')[0] ||
this.path
)
} catch (err) {
this._errors.name = err as Error;
}
}
return this._name || this.path;
}
getMethod(name = 'main') {
if (name === 'main' && this.main) return this.main;
if (typeof this.exports[name] === 'function') return this.exports[name];
throw Error(`No such method as '${name}' on module '${this.name}'`);
}
}
export type JSModuleFunction = (env: Environment, context: ConnectorContext<any>, modules: IMap<JSModule>, parameters: any, utilities: JSModuleUtilities) => Promise<any>;
export interface JSModuleUtilities {
getModule: <T>(modules: any, moduleName: string) => any & { main?: JSModuleFunction };
executeDoer: <T>(env: Environment, doerName: string, context: ConnectorContext<any>, coreConfig: T, runAsTask?: boolean, metadata?: any) => Promise<any>
}
export interface JSTask {
module: string;
code?: string;
parameters: IMap<any>;
method?: string;
export interface JSDoerConfig {
code: string;
}

@@ -5,3 +5,3 @@ export * from './cache-managers/cache-manager';

export * from './doers/doer';
export * from './doers/js-doer';
export * from './doers/js-doer.js';
export * from './doers/multi-doer';

@@ -8,0 +8,0 @@ export * from './environment';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc