fake-node 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +171 -1
- package/index.ts +135 -67
- package/package.json +29 -4
- package/tsconfig.json +10 -0
- package/web_only_globals.json +1049 -0
- package/LICENSE +0 -21
- package/globals.ts +0 -38
- package/modules/assert.ts +0 -205
- package/modules/buffer.ts +0 -4
- package/modules/fs.ts +0 -8
- package/modules/os.ts +0 -81
- package/modules/path.ts +0 -56
- package/modules/process.ts +0 -78
- package/modules/querystring.ts +0 -33
- package/modules/util.ts +0 -116
package/index.js
CHANGED
@@ -1 +1,171 @@
|
|
1
|
-
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
37
|
+
};
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
39
|
+
exports.FakeNode = exports.Process = void 0;
|
40
|
+
const assert_1 = __importDefault(require("assert"));
|
41
|
+
const module_buffer = __importStar(require("buffer"));
|
42
|
+
// @ts-ignore
|
43
|
+
const module_path = __importStar(require("path"));
|
44
|
+
const module_punycode = __importStar(require("punycode"));
|
45
|
+
const module_querystring = __importStar(require("querystring"));
|
46
|
+
// @ts-ignore
|
47
|
+
const module_readline = __importStar(require("readline"));
|
48
|
+
// @ts-ignore
|
49
|
+
const module_stream = __importStar(require("stream"));
|
50
|
+
// @ts-ignore
|
51
|
+
const module_string_decoder = __importStar(require("string_decoder"));
|
52
|
+
const module_test = __importStar(require("test"));
|
53
|
+
// @ts-ignore
|
54
|
+
const module_url = __importStar(require("url"));
|
55
|
+
// @ts-ignore
|
56
|
+
const module_util = __importStar(require("util"));
|
57
|
+
const web_only_globals_json_1 = __importDefault(require("./web_only_globals.json"));
|
58
|
+
// todo: properly implement eval
|
59
|
+
const DEFAULT_GLOBALS = { Infinity, NaN, undefined, eval, isFinite, isNaN, parseFloat, parseInt, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, escape, unescape, Object, Function, Boolean, Symbol, Error, AggregateError, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, Number, BigInt, Math, Date, String, RegExp, Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array, Map, Set, WeakMap, WeakSet, ArrayBuffer, SharedArrayBuffer, DataView, Atomics, JSON, WeakRef, FinalizationRegistry, Promise, Reflect, Proxy, Intl, AbortController, Blob, ByteLengthQueuingStrategy, atob, BroadcastChannel, btoa, clearInterval, clearTimeout, CloseEvent, CompressionStream, console, CountQueuingStrategy, Crypto, crypto, CryptoKey, CustomEvent, DecompressionStream, Event, EventSource, EventTarget, fetch, FormData, Headers, localStorage, MessageChannel, MessageEvent, MessagePort, Navigator, navigator, PerformanceEntry, PerformanceMark, PerformanceMeasure, PerformanceObserver, PerformanceObserverEntryList, performance, queueMicrotask, ReadableByteStreamController, Response, Request, sessionStorage, setInterval, setTimeout, Storage, structuredClone, SubtleCrypto, DOMException, TextDecoder, TextDecoderStream, TextEncoder, TextEncoderStream, TransformStreamDefaultController, URL, URLSearchParams, WebAssembly, WebSocket, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter };
|
60
|
+
for (const name of web_only_globals_json_1.default) {
|
61
|
+
Object.defineProperty(DEFAULT_GLOBALS, name, { get: () => { throw new ReferenceError(`${name} is not defined`); } });
|
62
|
+
}
|
63
|
+
class Process {
|
64
|
+
fakeNode;
|
65
|
+
pid;
|
66
|
+
argv = [];
|
67
|
+
argv0 = '';
|
68
|
+
module;
|
69
|
+
code;
|
70
|
+
path;
|
71
|
+
constructor(fakeNode, { path = '', code, module }) {
|
72
|
+
this.fakeNode = fakeNode;
|
73
|
+
this.pid = fakeNode.nextPid;
|
74
|
+
fakeNode.nextPid++;
|
75
|
+
fakeNode.processes.set(this.pid, this);
|
76
|
+
this.code = code;
|
77
|
+
this.path = path;
|
78
|
+
this.module = module ?? false;
|
79
|
+
}
|
80
|
+
run() {
|
81
|
+
let code;
|
82
|
+
if (this.module) {
|
83
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){__fakeNode_process__.fakeNode.modules.set('${this.module},(function(){${this.code};return module.exports;})());}`;
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){(function(){${this.code}})();}`;
|
87
|
+
}
|
88
|
+
let elt = document.createElement('script');
|
89
|
+
elt.textContent = code;
|
90
|
+
document.body.appendChild(elt);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
exports.Process = Process;
|
94
|
+
class FakeNode {
|
95
|
+
static nextId = 0;
|
96
|
+
id;
|
97
|
+
globalName;
|
98
|
+
modules = new Map();
|
99
|
+
builtinModules = new Map([
|
100
|
+
['assert', assert_1.default],
|
101
|
+
['buffer', module_buffer],
|
102
|
+
['path', module_path],
|
103
|
+
['punycode', module_punycode],
|
104
|
+
['querystring', module_querystring],
|
105
|
+
['readline', module_readline],
|
106
|
+
['stream', module_stream],
|
107
|
+
['string_decoder', module_string_decoder],
|
108
|
+
['test', module_test],
|
109
|
+
['url', module_url],
|
110
|
+
['util', module_util],
|
111
|
+
]);
|
112
|
+
globals;
|
113
|
+
processes = new Map();
|
114
|
+
nextPid = 3;
|
115
|
+
window = window;
|
116
|
+
constructor() {
|
117
|
+
this.id = FakeNode.nextId;
|
118
|
+
FakeNode.nextId++;
|
119
|
+
this.globalName = '__fakeNode_' + this.id + '__';
|
120
|
+
// @ts-ignore
|
121
|
+
globalThis[this.globalName] = this;
|
122
|
+
this.globals = Object.create(DEFAULT_GLOBALS);
|
123
|
+
Object.assign(this.globals, { require: this.require, Buffer: module_buffer.Buffer });
|
124
|
+
}
|
125
|
+
require(module) {
|
126
|
+
if (module.startsWith('fake-node:')) {
|
127
|
+
module = module.slice('fake-node:'.length);
|
128
|
+
}
|
129
|
+
else if (module.startsWith('node:')) {
|
130
|
+
module = module.slice('node:'.length);
|
131
|
+
}
|
132
|
+
if (this.modules.has(module)) {
|
133
|
+
return this.modules.get(module);
|
134
|
+
}
|
135
|
+
else if (this.builtinModules.has(module)) {
|
136
|
+
return this.builtinModules.get(module);
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
throw new Error(`cannot find module '${module}'`);
|
140
|
+
}
|
141
|
+
}
|
142
|
+
getGlobals(pid) {
|
143
|
+
const process = this.processes.get(pid);
|
144
|
+
if (process === undefined) {
|
145
|
+
throw new TypeError(`nonexistent PID in FakeNode.getGlobals call: ${pid}. If you do not know why this occured, it is probably a bug in fake-node. Please report it at https://github.com/speedydelete/fake-node/issues.`);
|
146
|
+
}
|
147
|
+
let scope = Object.create(this.globals);
|
148
|
+
scope.global = scope;
|
149
|
+
scope.globalThis = scope;
|
150
|
+
scope.__fakeNode_process__ = process;
|
151
|
+
if (process.path !== '') {
|
152
|
+
const pathParts = process.path.split('/');
|
153
|
+
scope.__dirname = pathParts.slice(0, -1).join('/');
|
154
|
+
scope.__filename = pathParts[pathParts.length - 1];
|
155
|
+
}
|
156
|
+
if (process.module !== false) {
|
157
|
+
scope.module = {
|
158
|
+
exports: {}
|
159
|
+
};
|
160
|
+
scope.exports = scope.module.exports;
|
161
|
+
}
|
162
|
+
return scope;
|
163
|
+
}
|
164
|
+
run(code) {
|
165
|
+
(new Process(this, { code, path: '/' })).run();
|
166
|
+
}
|
167
|
+
addModule(name, code) {
|
168
|
+
(new Process(this, { code, path: '/', module: name })).run();
|
169
|
+
}
|
170
|
+
}
|
171
|
+
exports.FakeNode = FakeNode;
|
package/index.ts
CHANGED
@@ -1,80 +1,148 @@
|
|
1
1
|
|
2
|
-
import
|
3
|
-
|
4
|
-
|
5
|
-
import * as
|
6
|
-
import * as
|
7
|
-
import * as
|
8
|
-
|
9
|
-
import * as
|
10
|
-
|
11
|
-
import * as
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
globalThis.__fakeNode_oldWd = globalThis.__fakeNode_wd;
|
21
|
-
if (path !== undefined) {
|
22
|
-
const splitPath = path.split('/');
|
23
|
-
readonly.__dirname = splitPath.slice(0, -1).join('/');
|
24
|
-
readonly.__filename = splitPath[splitPath.length - 1];
|
25
|
-
scope.__fakeNode_wd = readonly.__dirname;
|
26
|
-
}
|
27
|
-
Object.defineProperties(scope, Object.fromEntries(Object.entries(readonly).map(([name, value]) => [name, {value: value, writable: false}])));
|
28
|
-
return scope;
|
29
|
-
}
|
2
|
+
import module_assert from 'assert';
|
3
|
+
import * as module_buffer from 'buffer';
|
4
|
+
// @ts-ignore
|
5
|
+
import * as module_path from 'path';
|
6
|
+
import * as module_punycode from 'punycode';
|
7
|
+
import * as module_querystring from 'querystring';
|
8
|
+
// @ts-ignore
|
9
|
+
import * as module_readline from 'readline';
|
10
|
+
// @ts-ignore
|
11
|
+
import * as module_stream from 'stream';
|
12
|
+
// @ts-ignore
|
13
|
+
import * as module_string_decoder from 'string_decoder';
|
14
|
+
import * as module_test from 'test';
|
15
|
+
// @ts-ignore
|
16
|
+
import * as module_url from 'url';
|
17
|
+
// @ts-ignore
|
18
|
+
import * as module_util from 'util';
|
19
|
+
import WEB_ONLY_GLOBALS from './web_only_globals.json';
|
30
20
|
|
31
|
-
globalThis.__fakeNode_setup = setup;
|
32
21
|
|
33
|
-
|
34
|
-
|
22
|
+
// todo: properly implement eval
|
23
|
+
const DEFAULT_GLOBALS = {Infinity, NaN, undefined, eval, isFinite, isNaN, parseFloat, parseInt, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, escape, unescape, Object, Function, Boolean, Symbol, Error, AggregateError, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, Number, BigInt, Math, Date, String, RegExp, Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array, Map, Set, WeakMap, WeakSet, ArrayBuffer, SharedArrayBuffer, DataView, Atomics, JSON, WeakRef, FinalizationRegistry, Promise, Reflect, Proxy, Intl, AbortController, Blob, ByteLengthQueuingStrategy, atob, BroadcastChannel, btoa, clearInterval, clearTimeout, CloseEvent, CompressionStream, console, CountQueuingStrategy, Crypto, crypto, CryptoKey, CustomEvent, DecompressionStream, Event, EventSource, EventTarget, fetch, FormData, Headers, localStorage, MessageChannel, MessageEvent, MessagePort, Navigator, navigator, PerformanceEntry, PerformanceMark, PerformanceMeasure, PerformanceObserver, PerformanceObserverEntryList, performance, queueMicrotask, ReadableByteStreamController, Response, Request, sessionStorage, setInterval, setTimeout, Storage, structuredClone, SubtleCrypto, DOMException, TextDecoder, TextDecoderStream, TextEncoder, TextEncoderStream, TransformStreamDefaultController, URL, URLSearchParams, WebAssembly, WebSocket, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter};
|
24
|
+
for (const name of WEB_ONLY_GLOBALS) {
|
25
|
+
Object.defineProperty(DEFAULT_GLOBALS, name, {get: () => {throw new ReferenceError(`${name} is not defined`)}});
|
35
26
|
}
|
36
27
|
|
37
|
-
globalThis.__fakeNode_cleanup = cleanup;
|
38
28
|
|
39
|
-
|
40
|
-
code = `with(window.__fakeNode_setup(undefined,${JSON.stringify(argv)})){(function(){${code}})();window.__fakeNode_cleanup();}`;
|
41
|
-
let elt = document.createElement('script');
|
42
|
-
elt.textContent = code;
|
43
|
-
document.body.appendChild(elt);
|
44
|
-
}
|
29
|
+
export class Process {
|
45
30
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
31
|
+
fakeNode: FakeNode;
|
32
|
+
pid: number;
|
33
|
+
argv: string[] = [];
|
34
|
+
argv0: string = '';
|
35
|
+
module: false | string;
|
36
|
+
code: string;
|
37
|
+
path: string;
|
52
38
|
|
53
|
-
|
54
|
-
|
55
|
-
|
39
|
+
constructor(fakeNode: FakeNode, {path = '', code, module}: {path?: string, code: string, module?: false | string}) {
|
40
|
+
this.fakeNode = fakeNode;
|
41
|
+
this.pid = fakeNode.nextPid;
|
42
|
+
fakeNode.nextPid++;
|
43
|
+
fakeNode.processes.set(this.pid, this);
|
44
|
+
this.code = code;
|
45
|
+
this.path = path;
|
46
|
+
this.module = module ?? false;
|
47
|
+
}
|
56
48
|
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
run(): void {
|
50
|
+
let code: string;
|
51
|
+
if (this.module) {
|
52
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){__fakeNode_process__.fakeNode.modules.set('${this.module},(function(){${this.code};return module.exports;})());}`;
|
53
|
+
} else {
|
54
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){(function(){${this.code}})();}`;
|
55
|
+
}
|
56
|
+
let elt = document.createElement('script');
|
57
|
+
elt.textContent = code;
|
58
|
+
document.body.appendChild(elt);
|
59
|
+
}
|
60
60
|
|
61
|
-
function deleteBuiltinModule(name: string): void {
|
62
|
-
globalThis.__fakeNode_builtinModules.delete(name);
|
63
61
|
}
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
63
|
+
|
64
|
+
export class FakeNode {
|
65
|
+
|
66
|
+
static nextId: number = 0;
|
67
|
+
id: number;
|
68
|
+
globalName: string;
|
69
|
+
|
70
|
+
modules: Map<string, any> = new Map();
|
71
|
+
builtinModules: Map<string, any> = new Map<string, any>([
|
72
|
+
['assert', module_assert],
|
73
|
+
['buffer', module_buffer],
|
74
|
+
['path', module_path],
|
75
|
+
['punycode', module_punycode],
|
76
|
+
['querystring', module_querystring],
|
77
|
+
['readline', module_readline],
|
78
|
+
['stream', module_stream],
|
79
|
+
['string_decoder', module_string_decoder],
|
80
|
+
['test', module_test],
|
81
|
+
['url', module_url],
|
82
|
+
['util', module_util],
|
83
|
+
]);
|
84
|
+
|
85
|
+
globals: {[key: string]: any};
|
86
|
+
|
87
|
+
processes: Map<number, Process> = new Map();
|
88
|
+
nextPid: number = 3;
|
89
|
+
|
90
|
+
window: Window = window;
|
91
|
+
|
92
|
+
constructor() {
|
93
|
+
this.id = FakeNode.nextId;
|
94
|
+
FakeNode.nextId++;
|
95
|
+
this.globalName = '__fakeNode_' + this.id + '__';
|
96
|
+
// @ts-ignore
|
97
|
+
globalThis[this.globalName] = this;
|
98
|
+
this.globals = Object.create(DEFAULT_GLOBALS);
|
99
|
+
Object.assign(this.globals, {require: this.require, Buffer: module_buffer.Buffer});
|
100
|
+
}
|
101
|
+
|
102
|
+
require(module: string): any {
|
103
|
+
if (module.startsWith('fake-node:')) {
|
104
|
+
module = module.slice('fake-node:'.length);
|
105
|
+
} else if (module.startsWith('node:')) {
|
106
|
+
module = module.slice('node:'.length);
|
107
|
+
}
|
108
|
+
if (this.modules.has(module)) {
|
109
|
+
return this.modules.get(module);
|
110
|
+
} else if (this.builtinModules.has(module)) {
|
111
|
+
return this.builtinModules.get(module);
|
112
|
+
} else {
|
113
|
+
throw new Error(`cannot find module '${module}'`);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
getGlobals(pid: number): object {
|
118
|
+
const process = this.processes.get(pid);
|
119
|
+
if (process === undefined) {
|
120
|
+
throw new TypeError(`nonexistent PID in FakeNode.getGlobals call: ${pid}. If you do not know why this occured, it is probably a bug in fake-node. Please report it at https://github.com/speedydelete/fake-node/issues.`);
|
121
|
+
}
|
122
|
+
let scope: {[key: string]: any} = Object.create(this.globals);
|
123
|
+
scope.global = scope;
|
124
|
+
scope.globalThis = scope;
|
125
|
+
scope.__fakeNode_process__ = process;
|
126
|
+
if (process.path !== '') {
|
127
|
+
const pathParts = process.path.split('/');
|
128
|
+
scope.__dirname = pathParts.slice(0, -1).join('/');
|
129
|
+
scope.__filename = pathParts[pathParts.length - 1];
|
130
|
+
}
|
131
|
+
if (process.module !== false) {
|
132
|
+
scope.module = {
|
133
|
+
exports: {}
|
134
|
+
};
|
135
|
+
scope.exports = scope.module.exports;
|
136
|
+
}
|
137
|
+
return scope;
|
138
|
+
}
|
139
|
+
|
140
|
+
run(code: string): void {
|
141
|
+
(new Process(this, {code, path: '/'})).run();
|
142
|
+
}
|
143
|
+
|
144
|
+
addModule(name: string, code: string): void {
|
145
|
+
(new Process(this, {code, path: '/', module: name})).run();
|
146
|
+
}
|
147
|
+
|
80
148
|
}
|
package/package.json
CHANGED
@@ -1,14 +1,39 @@
|
|
1
1
|
{
|
2
2
|
"name": "fake-node",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.2.0",
|
4
4
|
"description": "A fake version of Node that works in the browser",
|
5
5
|
"license": "MIT",
|
6
6
|
"author": "speedydelete",
|
7
|
-
"type": "
|
7
|
+
"type": "commonjs",
|
8
8
|
"main": "index.js",
|
9
9
|
"homepage": "https://github.com/speedydelete/fake-node",
|
10
|
-
"repository":
|
10
|
+
"repository": {
|
11
|
+
"type": "git",
|
12
|
+
"url": "git+https://github.com/speedydelete/fake-node.git"
|
13
|
+
},
|
14
|
+
"bugs": {
|
15
|
+
"url": "https://github.com/speedydelete/fake-node/issues"
|
16
|
+
},
|
11
17
|
"scripts": {
|
12
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
18
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
19
|
+
"build": "tsc"
|
20
|
+
},
|
21
|
+
"dependencies": {
|
22
|
+
"assert": "^2.1.0",
|
23
|
+
"buffer": "^6.0.3",
|
24
|
+
"path": "^0.12.7",
|
25
|
+
"punycode": "^2.3.1",
|
26
|
+
"querystring": "^0.2.1",
|
27
|
+
"readline": "^1.3.0",
|
28
|
+
"stream": "^0.0.3",
|
29
|
+
"string_decoder": "^1.3.0",
|
30
|
+
"test": "^3.3.0",
|
31
|
+
"url": "^0.11.4",
|
32
|
+
"util": "^0.12.5"
|
33
|
+
},
|
34
|
+
"devDependencies": {
|
35
|
+
"@types/assert": "^1.5.11",
|
36
|
+
"@types/punycode": "^2.1.4",
|
37
|
+
"typescript": "^5.7.3"
|
13
38
|
}
|
14
39
|
}
|