fake-node 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +170 -1
- package/index.ts +131 -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,170 @@
|
|
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 ES_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 };
|
60
|
+
const NODE_AND_WEB_GLOBALS = { 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 };
|
61
|
+
class Process {
|
62
|
+
fakeNode;
|
63
|
+
pid;
|
64
|
+
argv = [];
|
65
|
+
argv0 = '';
|
66
|
+
module;
|
67
|
+
code;
|
68
|
+
path;
|
69
|
+
constructor(fakeNode, { path = '', code, module }) {
|
70
|
+
this.fakeNode = fakeNode;
|
71
|
+
this.pid = fakeNode.nextPid;
|
72
|
+
fakeNode.nextPid++;
|
73
|
+
fakeNode.processes.set(this.pid, this);
|
74
|
+
this.code = code;
|
75
|
+
this.path = path;
|
76
|
+
this.module = module ?? false;
|
77
|
+
}
|
78
|
+
run() {
|
79
|
+
let code;
|
80
|
+
if (this.module) {
|
81
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){__fakeNode_process__.fakeNode.modules.set('${this.module},(function(){${this.code};return module.exports;})());}`;
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
code = `with(${this.fakeNode.globalName}.getGlobals(${this.pid})){(function(){${this.code}})();}`;
|
85
|
+
}
|
86
|
+
let elt = document.createElement('script');
|
87
|
+
elt.textContent = code;
|
88
|
+
document.body.appendChild(elt);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
exports.Process = Process;
|
92
|
+
class FakeNode {
|
93
|
+
static nextId = 0;
|
94
|
+
id;
|
95
|
+
globalName;
|
96
|
+
modules = new Map();
|
97
|
+
builtinModules = new Map([
|
98
|
+
['assert', assert_1.default],
|
99
|
+
['buffer', module_buffer],
|
100
|
+
['path', module_path],
|
101
|
+
['punycode', module_punycode],
|
102
|
+
['querystring', module_querystring],
|
103
|
+
['readline', module_readline],
|
104
|
+
['stream', module_stream],
|
105
|
+
['string_decoder', module_string_decoder],
|
106
|
+
['test', module_test],
|
107
|
+
['url', module_url],
|
108
|
+
['util', module_util],
|
109
|
+
]);
|
110
|
+
globals;
|
111
|
+
processes = new Map();
|
112
|
+
nextPid = 3;
|
113
|
+
window = window;
|
114
|
+
constructor() {
|
115
|
+
this.id = FakeNode.nextId;
|
116
|
+
FakeNode.nextId++;
|
117
|
+
this.globalName = '__fakeNode_' + this.id + '__';
|
118
|
+
// @ts-ignore
|
119
|
+
globalThis[this.globalName] = this;
|
120
|
+
this.globals = { require: this.require, Buffer: module_buffer.Buffer };
|
121
|
+
Object.assign(this.globals, ES_GLOBALS);
|
122
|
+
for (const name of web_only_globals_json_1.default) {
|
123
|
+
Object.defineProperty(this.globals, name, { get: () => { throw new ReferenceError(`${name} is not defined`); } });
|
124
|
+
}
|
125
|
+
Object.assign(this.globals, NODE_AND_WEB_GLOBALS);
|
126
|
+
}
|
127
|
+
require(module) {
|
128
|
+
if (module.startsWith('fake-node:')) {
|
129
|
+
module = module.slice('fake-node:'.length);
|
130
|
+
}
|
131
|
+
else if (module.startsWith('node:')) {
|
132
|
+
module = module.slice('node:'.length);
|
133
|
+
}
|
134
|
+
if (this.modules.has(module)) {
|
135
|
+
return this.modules.get(module);
|
136
|
+
}
|
137
|
+
else if (this.builtinModules.has(module)) {
|
138
|
+
return this.builtinModules.get(module);
|
139
|
+
}
|
140
|
+
else {
|
141
|
+
throw new Error(`cannot find module '${name}'`);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
getGlobals(pid) {
|
145
|
+
const process = this.processes.get(pid);
|
146
|
+
if (process === undefined) {
|
147
|
+
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.`);
|
148
|
+
}
|
149
|
+
let scope = Object.create(this.globals);
|
150
|
+
scope.global = scope;
|
151
|
+
scope.globalThis = scope;
|
152
|
+
scope.__fakeNode_process__ = process;
|
153
|
+
if (process.path !== '') {
|
154
|
+
const pathParts = process.path.split('/');
|
155
|
+
scope.__dirname = pathParts.slice(0, -1).join('/');
|
156
|
+
scope.__filename = pathParts[pathParts.length - 1];
|
157
|
+
}
|
158
|
+
if (process.module !== false) {
|
159
|
+
scope.module = {
|
160
|
+
exports: {}
|
161
|
+
};
|
162
|
+
scope.exports = scope.module.exports;
|
163
|
+
}
|
164
|
+
return scope;
|
165
|
+
}
|
166
|
+
run(code) {
|
167
|
+
(new Process(this, { code, path: '/' })).run();
|
168
|
+
}
|
169
|
+
}
|
170
|
+
exports.FakeNode = FakeNode;
|
package/index.ts
CHANGED
@@ -1,80 +1,144 @@
|
|
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) {
|
141
|
+
(new Process(this, {code, path: '/'})).run();
|
142
|
+
}
|
143
|
+
|
80
144
|
}
|
package/package.json
CHANGED
@@ -1,14 +1,39 @@
|
|
1
1
|
{
|
2
2
|
"name": "fake-node",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.1",
|
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
|
}
|