-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
04bea55
commit 6e972b7
Showing
25 changed files
with
239 additions
and
358 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,34 @@ | ||
'use strict'; | ||
|
||
const { basename, extname, join, dirname } = require('node:path'); | ||
const { promises } = require('node:fs'); | ||
const { readFile, readdir } = promises; | ||
|
||
const Script = require('./src/script'); | ||
const { COMMON_CTX, MODULE_TYPES } = require('./src/config'); | ||
const { createContext, VMOptions } = require('./src/utils'); | ||
|
||
const readScript = async (filePath, options = {}) => { | ||
const src = await readFile(filePath, 'utf8'); | ||
if (!src) throw new SyntaxError(`File ${filePath} is empty`); | ||
return new Script(src, new VMOptions(options, { __filename: basename(filePath), __dirname: dirname(filePath) })); | ||
const { COMMON_CTX, MODULE_TYPES } = require('./lib/config'); | ||
const { createContext, scriptType } = require('./lib/utils'); | ||
const { readFile, readdir } = require('node:fs').promises; | ||
const execute = require('./lib/exec'); | ||
|
||
const readScript = async (path, options = {}) => { | ||
const src = await readFile(path, 'utf8'); | ||
if (!src) throw new SyntaxError(`File ${path} is empty`); | ||
const filename = basename(path); | ||
return execute(src, { ...options, filename, dir: dirname(path), type: scriptType(filename) }); | ||
}; | ||
|
||
const readDir = async (dir, options = {}, deep = true) => { | ||
const files = await readdir(dir, { withFileTypes: true }); | ||
const scripts = {}; | ||
|
||
const loader = async (file, filePath, options) => { | ||
const reader = file.isFile() ? readScript : readDir; | ||
const ext = extname(file.name); | ||
scripts[basename(file.name, MODULE_TYPES.includes(ext.slice(1)) ? ext : '')] = await reader(filePath, options); | ||
const loader = async (file, path) => { | ||
const [reader, ext] = [file.isFile() ? readScript : readDir, extname(file.name)]; | ||
scripts[basename(file.name, MODULE_TYPES.includes(ext.slice(1)) ? ext : '')] = await reader(path, options); | ||
}; | ||
|
||
// prettier-ignore | ||
await Promise.all(files.reduce((acc, file) => { | ||
if (file.isDirectory() && !deep) return acc; | ||
return acc.push(loader(file, join(dir, file.name), options)), acc; | ||
if ((file.isDirectory() && !deep)) return acc; | ||
return acc.push(loader(file, join(dir, file.name))), acc; | ||
}, [])); | ||
|
||
return scripts; | ||
}; | ||
|
||
const createScript = (src, options) => new Script(src, options); | ||
module.exports = { Script, readScript, readDir, createContext, createScript, COMMON_CTX }; | ||
module.exports = { execute, readScript, readDir, createContext, COMMON_CTX }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
'use strict'; | ||
|
||
const { createContext } = require('node:vm'); | ||
|
||
const WRAPPERS = { | ||
js: src => `{\n${src}\n}`, | ||
cjs: src => `(({exports, require, module, __filename, __dirname}) => {\n${src}\n});`, | ||
}; | ||
|
||
const MODULE_TYPES = ['js', 'cjs']; | ||
const RUN_OPTS = { timeout: 1000 }; | ||
const buffer = { Buffer, TextDecoder, TextEncoder }; | ||
const CTX_OPTS = { codeGeneration: { strings: false, wasm: false } }; | ||
const timers = { clearImmediate, clearInterval, clearTimeout, setInterval, setImmediate, setTimeout }; | ||
const ctx = Object.freeze({ ...timers, ...buffer, URL, URLSearchParams, console, queueMicrotask }); | ||
const [EMPTY_CTX, COMMON_CTX] = [createContext(Object.freeze({}), CTX_OPTS), createContext(ctx, CTX_OPTS)]; | ||
|
||
module.exports = { EMPTY_CTX, CTX_OPTS, COMMON_CTX, MODULE_TYPES, RUN_OPTS, WRAPPERS }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use strict'; | ||
|
||
const { wrapSource, createContext, scriptType } = require('./utils'); | ||
const createRequire = require('./require'); | ||
const { RUN_OPTS } = require('./config'); | ||
const vm = require('node:vm'); | ||
|
||
const cjs = (closure, options) => { | ||
const exports = {}; | ||
const module = { exports }; | ||
closure({ exports, module, ...options }); | ||
return module.exports; | ||
}; | ||
|
||
const execute = (src, settings = {}) => { | ||
const { script = {}, run = {}, ctx = {} } = settings; | ||
const type = settings.type ?? (settings.filename ? scriptType(settings.filename) : 'js'); | ||
const [filename, dir] = [settings.filename ?? '', settings.dir ?? process.cwd()]; | ||
const updatedSettings = { ...settings, script, run, ctx, filename, dir, type }; | ||
|
||
const isJS = type === 'js'; | ||
const defaultCTX = { require: createRequire(updatedSettings, execute), __filename: filename, __dirname: dir }; | ||
const runner = new vm.Script(wrapSource(src, type), { filename, lineOffset: -1 - isJS, ...script }); | ||
const context = isJS ? createContext(Object.freeze({ ...defaultCTX, ...ctx })) : createContext(ctx); | ||
const exports = runner.runInContext(context, { ...RUN_OPTS, ...run }); | ||
return isJS ? exports : cjs(exports, defaultCTX); | ||
}; | ||
|
||
module.exports = execute; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.