Initial commit

This commit is contained in:
2024-11-03 17:41:45 +01:00
commit c1640c1754
8043 changed files with 775536 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
on:
push:
branches-ignore:
- "gh-pages"
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
node: ["16", "18", "20"]
name: Node.js ${{ matrix.node }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
# cache: npm
- run: npm install
- run: npm test
env:
YARN_GPG: no

21
node_modules/node-retrieve-globals/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Zach Leatherman @zachleat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

91
node_modules/node-retrieve-globals/README.md generated vendored Normal file
View File

@@ -0,0 +1,91 @@
# node-retrieve-globals
Execute a string of JavaScript using Node.js and return the global variable values and functions.
* Supported on Node.js 16 and newer.
* Uses `var`, `let`, `const`, `function`, Array and Object [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment).
* Async-only as of v5.0.
* Can return any valid JS data type (including functions).
* Can provide an external data object as context to the local execution scope
* Transforms ESM import statements to work with current CommonJS limitations in Nodes `vm`.
* Uses [Nodes `vm` module to execute JavaScript](https://nodejs.org/api/vm.html#vmruninthiscontextcode-options)
* ⚠️ The `node:vm` module is not a security mechanism. Do not use it to run untrusted code.
* `codeGeneration` (e.g. `eval`) is disabled by default; use `setCreateContextOptions({codeGeneration: { strings: true, wasm: true } })` to re-enable.
* Works _with or without_ `--experimental-vm-modules` flag (for `vm.Module` support). _(v5.0.0 and newer)_
* Future-friendly feature tests for when `vm.Module` is stable and `--experimental-vm-modules` is no longer necessary. _(v5.0.0 and newer)_
* In use on:
* [JavaScript in Eleventy Front Matter](https://www.11ty.dev/docs/data-frontmatter-customize/#example-use-javascript-in-your-front-matter) (and [Demo](https://github.com/11ty/demo-eleventy-js-front-matter))
* [WebCs `<script webc:setup>`](https://www.11ty.dev/docs/languages/webc/#using-javascript-to-setup-your-component-webcsetup)
## Installation
Available on [npm](https://www.npmjs.com/package/node-retrieve-globals)
```
npm install node-retrieve-globals
```
## Usage
Works from Node.js with ESM and CommonJS:
```js
import { RetrieveGlobals } from "node-retrieve-globals";
// const { RetrieveGlobals } = await import("node-retrieve-globals");
```
And then:
```js
let code = `var a = 1;
const b = "hello";
function hello() {}`;
let vm = new RetrieveGlobals(code);
await vm.getGlobalContext();
```
Returns:
```js
{ a: 1, b: "hello", hello: function hello() {} }
```
### Pass in your own Data and reference it in the JavaScript code
```js
let code = `let ref = myData;`;
let vm = new RetrieveGlobals(code);
await vm.getGlobalContext({ myData: "hello" });
```
Returns:
```js
{ ref: "hello" }
```
### Advanced options
```js
// Defaults shown
let options = {
reuseGlobal: false, // re-use Node.js `global`, important if you want `console.log` to log to your console as expected.
dynamicImport: false, // allows `import()`
addRequire: false, // allows `require()`
experimentalModuleApi: false, // uses Module#_compile instead of `vm` (you probably dont want this and it is bypassed by default when vm.Module is supported)
};
await vm.getGlobalContext({}, options);
```
## Changelog
* `v6.0.0` Changes `import` and `require` to be project relative (not relative to this package on the file system).
* `v5.0.0` Removes sync API, swap to async-only. Better compatibility with `--experimental-vm-modules` Node flag.
* `v4.0.0` Swap to use `Module._compile` as a workaround for #2 (Node regression with experimental modules API in Node v20.10+)
* `v3.0.0` ESM-only package. Node 16+

30
node_modules/node-retrieve-globals/package.json generated vendored Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "node-retrieve-globals",
"version": "6.0.0",
"description": "Execute a string of JavaScript using Node.js and return the global variable values and functions.",
"type": "module",
"main": "retrieveGlobals.js",
"scripts": {
"test": "npx ava && cross-env NODE_OPTIONS='--experimental-vm-modules' npx ava"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zachleat/node-retrieve-globals.git"
},
"author": {
"name": "Zach Leatherman",
"email": "zachleatherman@gmail.com",
"url": "https://zachleat.com/"
},
"license": "MIT",
"devDependencies": {
"@zachleat/noop": "^1.0.3",
"ava": "^6.1.2",
"cross-env": "^7.0.3"
},
"dependencies": {
"acorn": "^8.1.3",
"acorn-walk": "^8.3.2",
"esm-import-transformer": "^3.0.2"
}
}

374
node_modules/node-retrieve-globals/retrieveGlobals.js generated vendored Normal file
View File

@@ -0,0 +1,374 @@
import vm from "vm";
import * as acorn from "acorn";
import * as walk from "acorn-walk";
import { ImportTransformer } from "esm-import-transformer";
import { createRequire, Module } from "module";
import { getWorkingDirectory } from "./util/getWorkingDirectory.js";
import { isSupported } from "./util/vmModules.js";
const IS_VM_MODULES_SUPPORTED = isSupported();
// `import` and `require` should both be relative to working directory (not this file)
const WORKING_DIRECTORY = getWorkingDirectory();
// TODO (feature) option to change `require` home base
const customRequire = createRequire(WORKING_DIRECTORY);
class RetrieveGlobals {
constructor(code, options) {
this.originalCode = code;
// backwards compat
if(typeof options === "string") {
options = {
filePath: options
};
}
this.options = Object.assign({
filePath: null,
transformEsmImports: false,
}, options);
if(IS_VM_MODULES_SUPPORTED) {
// Override: no code transformations if vm.Module works
this.options.transformEsmImports = false;
}
// set defaults
let acornOptions = {};
if(IS_VM_MODULES_SUPPORTED || this.options.transformEsmImports) {
acornOptions.sourceType = "module";
}
this.setAcornOptions(acornOptions);
this.setCreateContextOptions();
// transform `import ___ from ___` to `const ___ = await import(___)` to emulate *some* import syntax.
// Doesnt currently work with aliases (mod as name) or namespaced imports (* as name).
if(this.options.transformEsmImports) {
this.code = this.transformer.transformToDynamicImport();
} else {
this.code = this.originalCode;
}
}
get transformer() {
if(!this._transformer) {
this._transformer = new ImportTransformer(this.originalCode);
}
return this._transformer;
}
setAcornOptions(acornOptions) {
this.acornOptions = Object.assign({
ecmaVersion: "latest",
}, acornOptions );
}
setCreateContextOptions(contextOptions) {
this.createContextOptions = Object.assign({
codeGeneration: {
strings: false,
wasm: false,
}
}, contextOptions );
}
static _getProxiedContext(context = {}, options = {}) {
return new Proxy(context, {
get(target, propertyName) {
if(Reflect.has(target, propertyName)) {
return Reflect.get(target, propertyName);
}
if(options.reuseGlobal && Reflect.has(global, propertyName)) {
return global[propertyName];
}
if(options.addRequire && propertyName === "require") {
return customRequire;
}
}
});
}
// We prune function and variable declarations that arent globally declared
// (our acorn walker could be improved to skip non-global declarations, but this method is easier for now)
static _getGlobalVariablesReturnString(names, mode = "cjs") {
let s = [`let __globals = {};`];
for(let name of names) {
s.push(`if( typeof ${name} !== "undefined") { __globals.${name} = ${name}; }`);
}
return `${s.join("\n")};${mode === "esm" ? "\nexport default __globals;" : "return __globals;"}`
}
_setContextPrototype(context) {
// Context will fail isPlainObject and wont be merged in the data cascade properly without this prototype set
// See https://github.com/11ty/eleventy-utils/blob/main/src/IsPlainObject.js
if(!context || typeof context !== "object" || Array.isArray(context)) {
return;
}
if(!Object.getPrototypeOf(context).isPrototypeOf(Object.create({}))) {
Object.setPrototypeOf(context, Object.prototype);
// Go deep
for(let key in context) {
this._setContextPrototype(context[key]);
}
}
}
_getCode(code, options) {
let { async: isAsync, globalNames, experimentalModuleApi, data } = Object.assign({
async: true
}, options);
if(IS_VM_MODULES_SUPPORTED) {
return `${code}
${globalNames ? RetrieveGlobals._getGlobalVariablesReturnString(globalNames, "esm") : ""}`;
}
let prefix = [];
let argKeys = "";
let argValues = "";
// Dont use this when vm.Module is stable (or if the code doesnt have any imports!)
if(experimentalModuleApi) {
prefix = "module.exports = ";
if(typeof data === "object") {
let dataKeys = Object.keys(data);
if(dataKeys) {
argKeys = `{${dataKeys.join(",")}}`;
argValues = JSON.stringify(data, function replacer(key, value) {
if(typeof value === "function") {
throw new Error(`When using \`experimentalModuleApi\`, context data must be JSON.stringify friendly. The "${key}" property was type \`function\`.`);
}
return value;
});
}
}
}
return `${prefix}(${isAsync ? "async " : ""}function(${argKeys}) {
${code}
${globalNames ? RetrieveGlobals._getGlobalVariablesReturnString(globalNames, "cjs") : ""}
})(${argValues});`;
}
getGlobalNames(parsedAst) {
let globalNames = new Set();
let types = {
FunctionDeclaration(node) {
globalNames.add(node.id.name);
},
VariableDeclarator(node) {
// destructuring assignment Array
if(node.id.type === "ArrayPattern") {
for(let prop of node.id.elements) {
if(prop.type === "Identifier") {
globalNames.add(prop.name);
}
}
} else if(node.id.type === "ObjectPattern") {
// destructuring assignment Object
for(let prop of node.id.properties) {
if(prop.type === "Property") {
globalNames.add(prop.value.name);
}
}
} else if(node.id.name) {
globalNames.add(node.id.name);
}
},
// if imports arent being transformed to variables assignment, we need those too
ImportSpecifier(node) {
globalNames.add(node.imported.name);
}
};
walk.simple(parsedAst, types);
return globalNames;
}
_getParseError(code, err) {
// Acorn parsing error on script
let metadata = [];
if(this.options.filePath) {
metadata.push(`file: ${this.options.filePath}`);
}
if(err?.loc?.line) {
metadata.push(`line: ${err.loc.line}`);
}
if(err?.loc?.column) {
metadata.push(`column: ${err.loc.column}`);
}
return new Error(`Had trouble parsing with "acorn"${metadata.length ? ` (${metadata.join(", ")})` : ""}:
Message: ${err.message}
${code}`);
}
async _getGlobalContext(data, options) {
let {
async: isAsync,
reuseGlobal,
dynamicImport,
addRequire,
experimentalModuleApi,
} = Object.assign({
// defaults
async: true,
reuseGlobal: false,
// adds support for `require`
addRequire: false,
// allows dynamic import in `vm` (requires --experimental-vm-modules in Node v20.10+)
// https://github.com/nodejs/node/issues/51154
// TODO Another workaround possibility: We could use `import` outside of `vm` and inject the dependencies into context `data`
dynamicImport: false,
// Use Module._compile instead of vm
// Workaround for: https://github.com/zachleat/node-retrieve-globals/issues/2
// Warning: This method requires input `data` to be JSON stringify friendly.
// Dont use this if vm.Module is supported
// Dont use this if the code does not contain `import`s
experimentalModuleApi: !IS_VM_MODULES_SUPPORTED && this.transformer.hasImports(),
}, options);
if(IS_VM_MODULES_SUPPORTED) {
// Override: dont use this when modules are allowed.
experimentalModuleApi = false;
}
// These options are already supported by Module._compile
if(experimentalModuleApi) {
addRequire = false;
dynamicImport = false;
}
if(reuseGlobal || addRequire) {
// Re-use the parent `global` https://nodejs.org/api/globals.html
data = RetrieveGlobals._getProxiedContext(data || {}, {
reuseGlobal,
addRequire,
});
}
if(!data) {
data = {};
}
let context;
if(experimentalModuleApi || vm.isContext(data)) {
context = data;
} else {
context = vm.createContext(data, this.createContextOptions);
}
let parseCode;
let globalNames;
try {
parseCode = this._getCode(this.code, {
async: isAsync,
});
let parsedAst = acorn.parse(parseCode, this.acornOptions);
globalNames = this.getGlobalNames(parsedAst);
} catch(e) {
throw this._getParseError(parseCode, e);
}
try {
let execCode = this._getCode(this.code, {
async: isAsync,
globalNames,
experimentalModuleApi,
data: context,
});
if(experimentalModuleApi) {
let m = new Module();
m._compile(execCode, WORKING_DIRECTORY);
return m.exports;
}
let execOptions = {};
if(dynamicImport) {
// Warning: this option is part of the experimental modules API
execOptions.importModuleDynamically = (specifier) => import(specifier);
}
if(IS_VM_MODULES_SUPPORTED) {
// options.initializeImportMeta
let m = new vm.SourceTextModule(execCode, {
context,
initializeImportMeta: (meta, module) => {
meta.url = this.options.filePath || WORKING_DIRECTORY || module.identifier;
},
...execOptions,
});
// Thank you! https://stackoverflow.com/a/73282303/16711
await m.link(async (specifier, referencingModule) => {
const mod = await import(specifier);
const exportNames = Object.keys(mod);
return new vm.SyntheticModule(
exportNames,
function () {
exportNames.forEach(key => {
this.setExport(key, mod[key])
});
},
{
identifier: specifier,
context: referencingModule.context
}
);
});
await m.evaluate();
// TODO (feature) incorporate other esm `exports` here
return m.namespace.default;
}
return vm.runInContext(execCode, context, execOptions);
} catch(e) {
let type = "cjs";
if(IS_VM_MODULES_SUPPORTED) {
type = "esm";
} else if(experimentalModuleApi) {
type = "cjs-experimental";
}
throw new Error(`Had trouble executing Node script (type: ${type}):
Message: ${e.message}
${this.code}`);
}
}
async getGlobalContext(data, options) {
let ret = await this._getGlobalContext(data, Object.assign({
// whether or not the target code is executed asynchronously
// note that vm.Module will always be async-friendly
async: true,
}, options));
this._setContextPrototype(ret);
return ret;
}
}
export { RetrieveGlobals };

270
node_modules/node-retrieve-globals/test/test.js generated vendored Normal file
View File

@@ -0,0 +1,270 @@
import test from "ava";
import { RetrieveGlobals } from "../retrieveGlobals.js";
import { isSupported } from "../util/vmModules.js";
import { getWorkingDirectory } from "../util/getWorkingDirectory.js";
const IS_VM_MODULES_SUPPORTED = isSupported();
test("var", async t => {
let vm = new RetrieveGlobals(`var a = 1;`);
t.deepEqual(await vm.getGlobalContext(), { a: 1 });
});
test("isPlainObject", async t => {
// from eleventy-utils
function isPlainObject(value) {
if (value === null || typeof value !== "object") {
return false;
}
let proto = Object.getPrototypeOf(value);
return !proto || proto === Object.prototype;
};
let vm = new RetrieveGlobals("var a = 1;");
t.true(isPlainObject(await vm.getGlobalContext()));
});
test("isPlainObject deep", async t => {
// from eleventy-utils
function isPlainObject(value) {
if (value === null || typeof value !== "object") {
return false;
}
let proto = Object.getPrototypeOf(value);
return !proto || proto === Object.prototype;
};
let vm = new RetrieveGlobals("var a = { b: 1, c: { d: {} } };");
let obj = await vm.getGlobalContext();
t.true(isPlainObject(obj.a.c));
t.true(isPlainObject(obj.a.c.d));
});
test("isPlainObject deep circular", async t => {
// from eleventy-utils
function isPlainObject(value) {
if (value === null || typeof value !== "object") {
return false;
}
let proto = Object.getPrototypeOf(value);
return !proto || proto === Object.prototype;
};
let vm = new RetrieveGlobals(`
var a = { a: 1 };
var b = { b: a };
a.b = b;
`);
let obj = await vm.getGlobalContext();
t.true(isPlainObject(obj.a.b));
t.true(isPlainObject(obj.b.b));
});
test("var with data", async t => {
let vm = new RetrieveGlobals("var a = b;");
t.deepEqual(await vm.getGlobalContext({ b: 2 }), { a: 2 });
});
test("let with data", async t => {
let vm = new RetrieveGlobals("let a = b;");
t.deepEqual(await vm.getGlobalContext({ b: 2 }), { a: 2 });
});
test("const with data", async t => {
let vm = new RetrieveGlobals("const a = b;");
t.deepEqual(await vm.getGlobalContext({ b: 2 }), { a: 2 });
});
test("function", async t => {
let vm = new RetrieveGlobals("function testFunction() {}");
let ret = await vm.getGlobalContext();
t.true(typeof ret.testFunction === "function");
});
test("async let", async t => {
let vm = new RetrieveGlobals(`let b = await Promise.resolve(1);`);
let ret = await vm.getGlobalContext();
t.deepEqual(ret, { b: 1 });
});
test("destructured assignment via object", async t => {
let vm = new RetrieveGlobals(`const { a } = { a: 1 };`);
let ret = await vm.getGlobalContext();
t.is(typeof ret.a, "number");
t.is(ret.a, 1);
});
test("destructured assignment via Array", async t => {
let vm = new RetrieveGlobals(`const [a, b] = [1, 2];`);
let ret = await vm.getGlobalContext();
t.is(typeof ret.a, "number");
t.is(typeof ret.b, "number");
t.is(ret.a, 1);
t.is(ret.b, 2);
});
test("global: same console.log", async t => {
let vm = new RetrieveGlobals(`const b = console.log`);
let ret = await vm.getGlobalContext(undefined, {
reuseGlobal: false
});
t.not(ret.b, console.log);
let ret2 = await vm.getGlobalContext(undefined, {
reuseGlobal: true
});
t.is(ret2.b, console.log);
});
test("global: Same URL", async t => {
let vm = new RetrieveGlobals(`const b = URL;`);
let ret = await vm.getGlobalContext(undefined, {
reuseGlobal: true
});
t.is(ret.b, URL);
});
test("return array", async t => {
let vm = new RetrieveGlobals("let b = [1,2,3];");
let globals = await vm.getGlobalContext();
t.true(Array.isArray(globals.b));
t.deepEqual(globals.b, [1,2,3]);
});
test("`require` Compatibility", async t => {
let vm = new RetrieveGlobals(`const { noop } = require("@zachleat/noop");
const b = 1;`);
let ret = await vm.getGlobalContext(undefined, {
addRequire: true,
});
t.is(typeof ret.noop, "function");
t.is(ret.b, 1);
});
// Works with --experimental-vm-modules, remove this when modules are stable
if(IS_VM_MODULES_SUPPORTED) {
test("dynamic import (no code transformation) (requires --experimental-vm-modules in Node v20.10)", async t => {
let vm = new RetrieveGlobals(`const { noop } = await import("@zachleat/noop");`);
let ret = await vm.getGlobalContext(undefined, {
dynamicImport: true
});
t.is(typeof ret.noop, "function");
});
}
test("dynamic import (no code transformation) (experimentalModuleApi explicit true)", async t => {
let vm = new RetrieveGlobals(`const { noop } = await import("@zachleat/noop");`);
let ret = await vm.getGlobalContext(undefined, {
dynamicImport: true, // irrelevant for fallback case, important for --experimental-vm-modules support case
experimentalModuleApi: true, // Needs to be true here because there are no top level `import`
});
t.is(typeof ret.noop, "function");
});
// This would require --experimental-vm-modules in Node v20.10, but instead falls back to `experimentalModuleApi` automatically
test("ESM import", async t => {
let vm = new RetrieveGlobals(`import { noop } from "@zachleat/noop";
const b = 1;`, {
transformEsmImports: true,
});
let ret = await vm.getGlobalContext(undefined, {
// experimentalModuleApi: true, // implied
dynamicImport: true,
});
t.is(typeof ret.noop, "function");
t.is(ret.b, 1);
});
// This would require --experimental-vm-modules in Node v20.10, but instead falls back to `experimentalModuleApi` automatically
test("ESM import (experimentalModuleApi implied true)", async t => {
let vm = new RetrieveGlobals(`import { noop } from "@zachleat/noop";
const b = 1;`, {
transformEsmImports: true,
});
let ret = await vm.getGlobalContext(undefined, {
// experimentalModuleApi: true,
});
t.is(typeof ret.noop, "function");
t.is(ret.b, 1);
});
// This would require --experimental-vm-modules in Node v20.10, but instead falls back to `experimentalModuleApi` automatically
test("ESM import (experimentalModuleApi explicit true)", async t => {
// let vm = new RetrieveGlobals(`import { noop } from "@zachleat/noop";
let vm = new RetrieveGlobals(`import { noop } from "@zachleat/noop";
const b = 1;`, {
transformEsmImports: true, // overridden to false when --experimental-vm-modules
});
let ret = await vm.getGlobalContext(undefined, {
experimentalModuleApi: true, // overridden to false when --experimental-vm-modules
});
t.is(typeof ret.noop, "function");
t.is(ret.b, 1);
});
// This does not require --experimental-vm-modules in Node v20.10+ as it has no imports
test("No imports, with data", async t => {
let vm = new RetrieveGlobals(`const b = inputData;`, {
transformEsmImports: true,
});
let ret = await vm.getGlobalContext({ inputData: "hi" }, {
// experimentalModuleApi: true, // implied false
});
t.is(ret.b, "hi");
});
// This does not require --experimental-vm-modules in Node v20.10+ as it has no imports
test("No imports, with JSON unfriendly data", async t => {
let vm = new RetrieveGlobals(`const b = fn;`, {
transformEsmImports: true,
});
let ret = await vm.getGlobalContext({ fn: function() {} }, {
// experimentalModuleApi: true, // implied false
});
t.is(typeof ret.b, "function");
});
// This requires --experimental-vm-modules in Node v20.10+ and uses the experimentalModuleApi because it has imports
test("With imports, with JSON unfriendly data", async t => {
let vm = new RetrieveGlobals(`import { noop } from "@zachleat/noop";
const b = fn;`, {
transformEsmImports: true,
});
if(IS_VM_MODULES_SUPPORTED) {
// Works fine with --experimental-vm-modules
let ret = await vm.getGlobalContext({ fn: function() {} }, {
// experimentalModuleApi: true, // implied false
});
t.is(typeof ret.b, "function");
} else {
// This throws if --experimental-vm-modules not set
await t.throwsAsync(async () => {
let ret = await vm.getGlobalContext({ fn: function() {} }, {
// experimentalModuleApi: true, // implied true
});
});
}
});
if(IS_VM_MODULES_SUPPORTED) {
test("import.meta.url works", async t => {
let vm = new RetrieveGlobals(`const b = import.meta.url;`, {
filePath: import.meta.url
});
let ret = await vm.getGlobalContext();
t.is(ret.b, import.meta.url);
});
test("import.meta.url has the current working directory (if not passed via filePath)", async t => {
let vm = new RetrieveGlobals(`const b = import.meta.url;`, {
// filePath: import.meta.url
});
let ret = await vm.getGlobalContext();
t.is(ret.b, getWorkingDirectory());
});
}

View File

@@ -0,0 +1,18 @@
import path from "node:path";
import { pathToFileURL } from "node:url";
function addTrailingSlash(path) {
if(path.endsWith("/")) {
return path;
}
return path + "/";
}
function getWorkingDirectory() {
// Trailing slash required
// `import` and `require` should both be relative to working directory (not this file)
return addTrailingSlash(pathToFileURL(path.resolve(".")).toString());
}
export { getWorkingDirectory };

23
node_modules/node-retrieve-globals/util/vmModules.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
import vm from "vm";
function isSupported() {
// node --experimental-vm-modules …
if(process.execArgv.find(entry => entry == "--experimental-vm-modules")) {
return true;
}
// NODE_OPTIONS='--experimental-vm-modules' node …
if((process.env?.NODE_OPTIONS || "").split(" ").find(entry => entry == "--experimental-vm-modules")) {
return true;
}
// Feature test for a future when --experimental-vm-modules is not needed
// and vm.Module is stable:
try {
new vm.SourceTextModule(`/* hi */`);
return true;
} catch(e) {}
return false;
}
export { isSupported };