Skip to content

Commit 6f00a2a

Browse files
authored
Merge pull request #6 from astrohelm/dev
Isolation v1.6.0
2 parents acd2e56 + 278376d commit 6f00a2a

File tree

5 files changed

+337
-260
lines changed

5 files changed

+337
-260
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## [Unreleased][unreleased]
44

5+
## [1.6.0][] - 2023-11-26
6+
7+
- Code quality improvements
8+
- Changelog linking fixes
9+
- Npm published
10+
511
## [1.5.0][] - 2023-10-30
612

713
- Depth field, now you can limit depth
@@ -85,6 +91,11 @@
8591
- Quality of life improvements
8692
- Massive README update, documentation improvement
8793

88-
[unreleased]: https://github.com/astrohelm/astroctx/compare/v1.1.0...HEAD
94+
[unreleased]: https://github.com/astrohelm/astroctx/compare/v1.6.0...HEAD
95+
[1.6.0]: https://github.com/astrohelm/astroctx/compare/v1.5.0...v1.6.0
96+
[1.5.0]: https://github.com/astrohelm/astroctx/compare/v1.4.0...v1.5.0
97+
[1.4.0]: https://github.com/astrohelm/astroctx/compare/v1.3.0...v1.4.0
98+
[1.3.0]: https://github.com/astrohelm/astroctx/compare/v1.2.0...v1.3.0
99+
[1.2.0]: https://github.com/astrohelm/astroctx/compare/v1.1.0...v1.2.0
89100
[1.1.0]: https://github.com/astrohelm/astroctx/compare/v1.0.0...v1.1.0
90101
[1.0.0]: https://github.com/astrohelm/astroctx/releases/tag/v1.0.0

lib/parser.js

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,49 @@
11
'use strict';
22

3-
const [REGEXP_JS, READDIR_OPTS] = [/^\.[cme]?js$/, { withFileTypes: true }];
4-
const [Script, { checkAccess }] = [require('./script'), require('./utils')];
53
const { basename, extname, join, dirname } = require('node:path');
64
const { readFile, readdir, stat } = require('node:fs').promises;
5+
const { prepare, execute } = require('./script');
6+
const { checkAccess } = require('./utils');
7+
const READ_OPTS = { withFileTypes: true };
8+
const JS_EXT = /^\.[cme]?js$/;
9+
module.exports = from;
710

8-
const from = async (src, options = {}) => {
11+
async function from(src, options = {}) {
912
if (src !== '.' && src !== '..' && basename(src) === src) {
1013
const { prepare, ...estimated } = options;
11-
if (prepare) return Script.prepare(src, estimated);
12-
return new Script(src, estimated);
14+
if (prepare) return prepare(src, estimated);
15+
return execute(src, estimated);
1316
}
1417
const reader = (await stat(src)).isDirectory() ? from.dir : from.file;
15-
const result = await reader(src, options);
16-
return result;
17-
};
18+
return reader(src, options);
19+
}
1820

1921
from.file = async (path, options = {}) => {
2022
const src = await readFile(path, 'utf8');
2123
if (!src) throw new SyntaxError(`File ${path} is empty`);
22-
const [filename, dir] = [basename(path), dirname(path)];
23-
const runner = options.prepare ? Script.prepare : Script.execute;
24+
const { 0: filename, 1: dir } = [basename(path), dirname(path)];
25+
const runner = options.prepare ? prepare : execute;
2426
return runner(src, { ...options, filename, dir, prepare: undefined });
2527
};
2628

2729
from.dir = (src, options = {}) => {
28-
const { depth: max = true, ...estimated } = options;
29-
const isAllowed = checkAccess.bind(null, 'reader', estimated.access);
30-
const pull = async (src, depth) => {
31-
const dontGoDeep = typeof max === 'number' && depth + 1 > max;
32-
const files = await readdir(src, READDIR_OPTS);
30+
const { depth: max = true, access } = options;
31+
const isAllowed = checkAccess.bind(null, 'reader', access);
32+
const pull = async (src, depth = 1) => {
33+
const futher = typeof max === 'number' && depth + 1 > max;
34+
const files = await readdir(src, READ_OPTS);
3335
const scripts = {};
3436
// prettier-ignore
3537
await Promise.all(files.map(async file => {
36-
const [path, isDir, ext] = [join(src, file.name), file.isDirectory(), extname(file.name)];
37-
if (!isAllowed(path) || (isDir && dontGoDeep)) return;
38+
const isDir = file.isDirectory();
39+
const path = join(src, file.name);
40+
if (!isAllowed(path) || (isDir && futher)) return;
3841
const promise = isDir ? pull(path, depth + 1) : from.file(path, options);
39-
const name = basename(file.name, ext.match(REGEXP_JS) ? ext : '');
42+
const ext = extname(file.name);
43+
const name = basename(file.name, ext.match(JS_EXT) ? ext : '');
4044
scripts[name] = await promise;
4145
}));
4246
return Object.assign({}, scripts);
4347
};
44-
return pull(src, 1);
48+
return pull(src);
4549
};
46-
47-
module.exports = from;

lib/script.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
'use strict';
22

3+
const { Script: VM, createContext } = require('node:vm');
4+
const createRequire = require('./require');
5+
module.exports = Script;
6+
37
const RSTRICT = /['"]use strict['"];\n?/g;
4-
const [{ Script: VM, createContext }, createRequire] = [require('node:vm'), require('./require')];
58
const cjs = src => `((exports, require, module, __filename, __dirname) => {\n${src}\n});`;
69
const wrap = src => `'use strict';\n` + cjs(src.replace(RSTRICT, ''));
710

8-
const Script = function (src, opts = {}) {
11+
function Script(src, opts = {}) {
912
if (!new.target) return new Script(src, opts);
10-
const { script = {}, run = {}, ctx = {}, filename = 'ISO', dir = process.cwd() } = opts;
11-
const machine = new VM(wrap(src), { filename, lineOffset: -1 - !src.match(RSTRICT), ...script });
13+
const { script = {}, run = {}, ctx = {}, filename = 'Astro', dir = process.cwd() } = opts;
14+
const lineOffset = src.includes('use strict') ? -1 : -2;
15+
const machine = new VM(wrap(src), { filename, lineOffset, ...script });
1216
const require = createRequire({ ...opts, dir }, Script.execute);
13-
const context = Script.sandbox(ctx);
17+
const context = Script.sandbox(Object.freeze(ctx));
1418

15-
[this.name, this.dir] = [filename, dir];
19+
this.name = filename;
20+
this.dir = dir;
1621
this.execute = (ctx = context) => {
1722
const module = { exports: {} };
1823
const closure = machine.runInContext(Script.sandbox(ctx), { timeout: 1000, ...run });
1924
return closure(module.exports, require, module, this.name, this.dir), module.exports;
2025
};
21-
22-
return this;
23-
};
26+
}
2427

2528
Script.prepare = (src, opts) => new Script(src, opts);
2629
Script.execute = (src, opts) => new Script(src, opts).execute();
2730
Script.sandbox = Object.assign((ctx, mode = false) => {
2831
if (!ctx) return Script.sandbox.EMPTY;
29-
return createContext(ctx, {
30-
...Script.sandbox.OPTIONS,
31-
preventEscape: mode ? 'afterEvaluate' : '',
32-
});
32+
const preventEscape = mode ? 'afterEvaluate' : '';
33+
return createContext(ctx, { ...Script.sandbox.OPTIONS, preventEscape });
3334
}, require('./ctx'));
34-
35-
module.exports = Script;

0 commit comments

Comments
 (0)