Skip to content

Commit 5adf99a

Browse files
committed
Added method jsPythonForNode
1 parent 70b1cd0 commit 5adf99a

File tree

7 files changed

+143
-81
lines changed

7 files changed

+143
-81
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "jspython-cli",
3-
"version": "2.1.6",
3+
"version": "2.1.7",
44
"description": "CLI for jspython. Allows you to run jspython (*.jspy) files",
5-
"main": "src/index.ts",
5+
"main": "dist/index.js",
66
"bin": {
77
"jspython": "bin/jspython"
88
},

rollup.config.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import copy from 'rollup-plugin-copy'
33

44
const pkg = require('./package.json');
55

6-
export default {
7-
input: pkg.main,
6+
export default [{
7+
input: 'src/index.ts',
88
output: { file: pkg.bin['jspython'], format: 'cjs', sourcemap: true, compact: true, banner: '#!/usr/bin/env node' },
99
plugins: [
1010
typescript({
@@ -17,4 +17,17 @@ export default {
1717
})
1818
],
1919
external: ['arg', 'fs', 'jspython-interpreter', 'http', 'https']
20-
};
20+
}, {
21+
input: 'src/jspython-node.ts',
22+
output: [
23+
{
24+
file: 'dist/index.js',
25+
format: 'cjs'
26+
}
27+
],
28+
plugins: [
29+
typescript({
30+
clean: true
31+
})
32+
]
33+
}];

src/index.ts

Lines changed: 9 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import arg from 'arg';
22
import fs from 'fs';
3-
import { jsPython, Interpreter, PackageLoader } from 'jspython-interpreter';
3+
import { Interpreter } from 'jspython-interpreter';
4+
import { jsPythonForNode } from './jspython-node';
5+
import { InterpreterOptions } from './types';
6+
import { trimChar } from './utils';
47
var util = require('util');
58

69
const pkg = require('../package.json');
710

8-
const context: any = {
9-
asserts: [],
10-
params: {}
11-
}
12-
1311
// catch the uncaught errors that weren't wrapped in a domain or try catch statement
1412
// do not use this in modules, but only in applications, as otherwise we could have multiple of these bound
1513
process
@@ -27,20 +25,8 @@ const initialScope: Record<string, any> = {
2725
};
2826

2927
const rootFolder = process.cwd().split('\\').join('/');
30-
const interpreter: Interpreter = jsPython() as Interpreter;
3128
const options = getOptionsFromArguments(process.argv);
32-
33-
function trimChar(text: string, charToRemove: string): string {
34-
while (text.charAt(0) == charToRemove) {
35-
text = text.substring(1);
36-
}
37-
38-
while (text.charAt(text.length - 1) == charToRemove) {
39-
text = text.substring(0, text.length - 1);
40-
}
41-
42-
return text;
43-
}
29+
const interpreter: Interpreter = jsPythonForNode(options) as Interpreter;
4430

4531
async function initialize(baseSource: string) {
4632

@@ -72,16 +58,9 @@ async function initialize(baseSource: string) {
7258

7359
Object.assign(initialScope, app);
7460
}
75-
76-
initialScope.assert = (condition: boolean, name?: string, description?: string) => context.asserts.push({ condition, name, description });
77-
initialScope.showAsserts = () => console.table(context.asserts);
78-
initialScope.params = (name: string) => {
79-
const value = context.params[name];
80-
return value === undefined ? null : value;
81-
}
8261
}
8362

84-
function getOptionsFromArguments(rawArgs: string[]) {
63+
function getOptionsFromArguments(rawArgs: string[]): InterpreterOptions {
8564
const args = arg({
8665
'--file': String,
8766
'--srcRoot': String,
@@ -108,7 +87,7 @@ function getOptionsFromArguments(rawArgs: string[]) {
10887
return obj;
10988
}, {});
11089

111-
const res = {
90+
const res: InterpreterOptions = {
11291
file: args['--file'] || (rawArgs.length === 3 && !rawArgs[2].startsWith('-') ? rawArgs[2] : ''),
11392
version: args['--version'],
11493
output: args['--output'],
@@ -121,52 +100,11 @@ function getOptionsFromArguments(rawArgs: string[]) {
121100
res.srcRoot = res.srcRoot + '/';
122101
}
123102

124-
context.params = { ...res, ...params };
103+
res.params = { ...res, ...params };
125104

126105
return res;
127106
}
128107

129-
function moduleLoader(filePath: string): Promise<string> {
130-
filePath = trimChar(trimChar(filePath, '/'), '.');
131-
let fileName = `${options.srcRoot}${filePath}.jspy`;
132-
133-
if (!fs.existsSync(fileName)) {
134-
fileName = `${options.srcRoot}${filePath}`;
135-
}
136-
137-
if (!fs.existsSync(fileName)) {
138-
fileName = `src/${filePath}`;
139-
}
140-
141-
try {
142-
const script = fs.readFileSync(fileName, 'utf8');
143-
return Promise.resolve(script);
144-
} catch (e) {
145-
console.log('* module loader error ', e?.message || e)
146-
return Promise.reject(e);
147-
}
148-
}
149-
150-
/**@type {PackageLoader} */
151-
function packageLoader(packageName: string): any {
152-
try {
153-
if (['fs', 'path', 'readline', 'timers', 'child_process', 'util', 'zlib', 'stream', 'net', 'https', 'http', 'events', 'os', 'buffer']
154-
.includes(packageName)) {
155-
return require(packageName)
156-
}
157-
158-
if (packageName.toLowerCase().endsWith('.js') || packageName.toLowerCase().endsWith('.json')) {
159-
return require(`${rootFolder}/${options.srcRoot}${packageName}`)
160-
}
161-
162-
return require(`${rootFolder}/node_modules/${packageName}`);
163-
}
164-
catch (err) {
165-
console.log('Import Error: ', err?.message || err);
166-
throw err;
167-
}
168-
}
169-
170108
async function main() {
171109
if (!options.file && !options.version) {
172110
console.log(interpreter.jsPythonInfo());
@@ -207,14 +145,10 @@ async function main() {
207145
}
208146

209147
const scripts = fs.readFileSync(fileName, 'utf8');
210-
context.asserts.length = 0;
211148
console.log(interpreter.jsPythonInfo())
212149
console.log(`> ${options.file}`)
213150
try {
214-
const res = await interpreter
215-
.registerPackagesLoader(packageLoader as PackageLoader)
216-
.registerModuleLoader(moduleLoader)
217-
.evaluate(scripts, initialScope, options.entryFunction || undefined, options.file);
151+
const res = await interpreter.evaluate(scripts, initialScope, options.entryFunction || undefined, options.file);
218152

219153
if (!!res || res === 0) {
220154
console.log('>', res);

src/jspython-node.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import fs from 'fs';
2+
import { jsPython, Interpreter, PackageLoader } from 'jspython-interpreter';
3+
import { InterpreterOptions } from './types';
4+
import { trimChar } from './utils';
5+
6+
const rootFolder = process.cwd().split('\\').join('/');
7+
const initialScope: any = {};
8+
9+
type NodeJsInterpreter = Interpreter & { evaluateFile: (fileName: string) => Promise<any> };
10+
11+
const context: any = {
12+
asserts: [],
13+
params: {}
14+
}
15+
16+
initialScope.assert = (condition: boolean, name?: string, description?: string) => context.asserts.push({ condition, name, description });
17+
initialScope.showAsserts = () => console.table(context.asserts);
18+
initialScope.params = (name: string) => {
19+
const value = context.params[name];
20+
return value === undefined ? null : value;
21+
}
22+
23+
export function jsPythonForNode(options: InterpreterOptions = {
24+
srcRoot: ''
25+
}): NodeJsInterpreter {
26+
const interpreter: NodeJsInterpreter = jsPython() as NodeJsInterpreter;
27+
Object.assign(context.params, options.params);
28+
29+
interpreter
30+
.registerPackagesLoader(packageLoader as PackageLoader)
31+
.registerModuleLoader(moduleLoader);
32+
33+
const evaluate = interpreter.evaluate;
34+
interpreter.evaluate = function() {
35+
context.asserts.length = 0;
36+
return evaluate.apply(interpreter, arguments as any);
37+
}
38+
39+
interpreter.evaluateFile = function(filePath: string) {
40+
const script = getScript(filePath);
41+
return interpreter.evaluate(script, {});
42+
}
43+
44+
return interpreter;
45+
46+
47+
function moduleLoader(filePath: string): Promise<string> {
48+
filePath = trimChar(trimChar(filePath, '/'), '.');
49+
let fileName = `${options.srcRoot}${filePath}.jspy`;
50+
51+
if (!fs.existsSync(fileName)) {
52+
fileName = `${options.srcRoot}${filePath}`;
53+
}
54+
55+
if (!fs.existsSync(fileName)) {
56+
fileName = `src/${filePath}`;
57+
}
58+
59+
try {
60+
const script = fs.readFileSync(fileName, 'utf8');
61+
return Promise.resolve(script);
62+
} catch (e) {
63+
console.log('* module loader error ', e?.message || e)
64+
return Promise.reject(e);
65+
}
66+
}
67+
68+
/**@type {PackageLoader} */
69+
function packageLoader(packageName: string): any {
70+
try {
71+
if (['fs', 'path', 'readline', 'timers', 'child_process', 'util', 'zlib', 'stream', 'net', 'https', 'http', 'events', 'os', 'buffer']
72+
.includes(packageName)) {
73+
return require(packageName)
74+
}
75+
76+
if (packageName.toLowerCase().endsWith('.js') || packageName.toLowerCase().endsWith('.json')) {
77+
return require(`${rootFolder}/${options.srcRoot}${packageName}`)
78+
}
79+
80+
return require(`${rootFolder}/node_modules/${packageName}`);
81+
}
82+
catch (err) {
83+
console.log('Import Error: ', err?.message || err);
84+
throw err;
85+
}
86+
}
87+
}
88+
89+
function getScript(fileName: string): string {
90+
if (!fs.existsSync(fileName)) {
91+
throw Error(`File not found`)
92+
}
93+
94+
const scripts = fs.readFileSync(fileName, 'utf8');
95+
return scripts;
96+
}

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface InterpreterOptions {
2+
file?: string;
3+
srcRoot: string;
4+
entryFunction?: string;
5+
version?: boolean;
6+
output?: string;
7+
params?: Record<string, unknown>;
8+
}

src/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function trimChar(text: string, charToRemove: string): string {
2+
while (text.charAt(0) == charToRemove) {
3+
text = text.substring(1);
4+
}
5+
6+
while (text.charAt(text.length - 1) == charToRemove) {
7+
text = text.substring(0, text.length - 1);
8+
}
9+
10+
return text;
11+
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
4040

4141
/* Module Resolution Options */
42-
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
42+
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
4343
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
4444
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
4545
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */

0 commit comments

Comments
 (0)