pub const BUILTIN_MODULES: &[&str] = &[
"util",
"path",
"fs",
"os",
"buffer",
"stream",
"events",
"crypto",
"url",
"querystring",
"assert",
"constants",
"http",
"https",
"net",
"tls",
"child_process",
"cluster",
"dgram",
"dns",
"readline",
"repl",
"timers",
"tty",
"v8",
"vm",
"zlib",
];
pub fn is_builtin(specifier: &str) -> bool {
let name = specifier.split('/').next().unwrap_or(specifier);
BUILTIN_MODULES.contains(&name)
}
pub fn get_builtin_stub(name: &str) -> &'static str {
match name {
"util" => {
r#"
var types = {};
if (typeof ArrayBuffer !== 'undefined') {
types.isArrayBuffer = function(v) { return v instanceof ArrayBuffer; };
}
types.isDate = function(v) { return v instanceof Date; };
types.isMap = function(v) { return v && typeof v === 'object' && v.constructor === Map; };
types.isRegExp = function(v) { return v instanceof RegExp; };
types.isSet = function(v) { return v && typeof v === 'object' && v.constructor === Set; };
types.isTypedArray = function(v) {
return v && ArrayBuffer.isView && ArrayBuffer.isView(v) && !(v instanceof DataView);
};
module.exports = {
types: types,
inspect: function(o) { return JSON.stringify(o); },
format: function() {
var args = Array.prototype.slice.call(arguments);
var fmt = args.shift();
return fmt.replace(/%[sdjo]/g, function() { return String(args.shift()); });
}
};
"#
}
"path" => {
r#"
module.exports = {
join: function() { return Array.prototype.slice.call(arguments).join('/').replace(/\/+/g, '/'); },
resolve: function() { return Array.prototype.slice.call(arguments).join('/').replace(/\/+/g, '/'); },
dirname: function(p) { return p.split('/').slice(0,-1).join('/'); },
basename: function(p) { return p.split('/').pop() || ''; },
extname: function(p) { var m = p.match(/\.[^.]+$/); return m ? m[0] : ''; },
sep: '/',
delimiter: ':'
};
"#
}
"fs" => {
r#"
// Enhanced File System module implementation
var path = require('path');
// In a real implementation, these would interface with the file system
// For now, we provide mock implementations
var fsMock = {
readFileSync: function(filename, options) {
// Mock implementation
return '{}';
},
writeFileSync: function(filename, data, options) {
// Mock implementation
return undefined;
},
existsSync: function(path) {
// Mock implementation
return false;
},
readdirSync: function(path) {
// Mock implementation
return [];
},
statSync: function(path) {
// Mock implementation
return {
isFile: function() { return true; },
isDirectory: function() { return false; },
size: 0,
mtime: new Date(),
atime: new Date(),
ctime: new Date()
};
},
mkdirSync: function(path, options) {
// Mock implementation
return undefined;
},
rmdirSync: function(path) {
// Mock implementation
return undefined;
},
unlinkSync: function(path) {
// Mock implementation
return undefined;
},
createReadStream: function(path, options) {
// Mock implementation
var EventEmitter = require('events');
var stream = new EventEmitter();
stream.readable = true;
stream.pipe = function(dest) {
this.on('data', function(chunk) {
dest.write(chunk);
});
this.on('end', function() {
dest.end();
});
return dest;
};
return stream;
},
createWriteStream: function(path, options) {
// Mock implementation
var EventEmitter = require('events');
var stream = new EventEmitter();
stream.writable = true;
stream.write = function(data) {
this.emit('data', data);
return true;
};
stream.end = function(data) {
if (data) this.write(data);
this.emit('finish');
this.emit('end');
};
return stream;
},
appendFileSync: function(filename, data, options) {
// Mock implementation
return undefined;
},
readFile: function(filename, options, callback) {
// Async mock implementation
if (typeof options === 'function') {
callback = options;
options = undefined;
}
setTimeout(function() {
callback(null, '{}');
}, 0);
},
writeFile: function(filename, data, options, callback) {
// Async mock implementation
if (typeof options === 'function') {
callback = options;
options = undefined;
}
setTimeout(function() {
callback(null);
}, 0);
},
access: function(path, mode, callback) {
// Async mock implementation
if (typeof mode === 'function') {
callback = mode;
mode = undefined;
}
setTimeout(function() {
callback(null);
}, 0);
},
accessSync: function(path, mode) {
// Sync mock implementation
return undefined;
},
copyFile: function(src, dest, mode, callback) {
// Async mock implementation
if (typeof mode === 'function') {
callback = mode;
mode = 0;
}
setTimeout(function() {
callback(null);
}, 0);
},
copyFileSync: function(src, dest, mode) {
// Sync mock implementation
return undefined;
}
};
module.exports = fsMock;
"#
}
"os" => {
r#"
module.exports = {
platform: function() { return 'unknown'; },
arch: function() { return 'unknown'; },
tmpdir: function() { return '/tmp'; },
homedir: function() { return '/'; }
};
"#
}
"buffer" => {
r#"
// Enhanced Buffer implementation
function Buffer(subject, encodingOrOffset, length) {
if (typeof subject === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new TypeError('Encoding must not be specified');
}
return Buffer.alloc(subject, encodingOrOffset);
}
if (typeof subject === 'string') {
if (typeof encodingOrOffset === 'string') {
encodingOrOffset = 'utf8';
}
return Buffer.from(subject, encodingOrOffset);
}
if (typeof subject === 'object' && subject.type === 'Buffer') {
// Handle conversion from existing Buffer
return new Buffer(subject.data);
}
// Handle arrays, ArrayBuffer, etc.
return new Buffer(subject);
}
Buffer.alloc = function(size, fill, encoding) {
if (typeof size !== 'number') {
throw new TypeError('Size must be a number');
}
var buf = new Buffer(size);
if (fill !== undefined) {
if (typeof encoding === 'string') {
encoding = undefined;
}
return buf.fill(fill, encoding);
}
return buf;
};
Buffer.from = function(array, encodingOrOffset, length) {
if (typeof array === 'string') {
var encoding = encodingOrOffset;
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8';
}
var buf = new Buffer(array.length);
buf.write(array, encoding);
return buf;
}
if (array.buffer instanceof ArrayBuffer) {
// Handle TypedArrays and ArrayBuffer
return new Buffer(new Uint8Array(array.buffer));
}
if (Array.isArray(array)) {
return new Buffer(array);
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object');
};
Buffer.prototype.write = function(string, offset, length, encoding) {
if (typeof offset === 'string') {
encoding = offset;
offset = 0;
} else if (typeof offset === 'undefined' || offset < 0) {
offset = 0;
}
if (typeof length === 'string') {
encoding = length;
length = undefined;
} else if (typeof length === 'undefined' || length < 0) {
length = this.length - offset;
}
encoding = encoding || 'utf8';
// Simplified implementation
for (var i = 0; i < Math.min(length, this.length - offset) && i < string.length; i++) {
this[offset + i] = string.charCodeAt(i) & 0xFF;
}
return i;
};
Buffer.prototype.toString = function(encoding, start, end) {
encoding = encoding || 'utf8';
start = start || 0;
end = end || this.length;
var result = '';
for (var i = start; i < end; i++) {
result += String.fromCharCode(this[i] & 0xFF);
}
return result;
};
Buffer.isBuffer = function(obj) {
return obj instanceof Buffer;
};
Buffer.byteLength = function(string, encoding) {
encoding = encoding || 'utf8';
// Simplified implementation
return string.length;
};
Buffer.concat = function(list, totalLength) {
if (list.length === 0) {
return new Buffer(0);
}
if (totalLength === undefined) {
totalLength = 0;
for (var i = 0; i < list.length; i++) {
totalLength += list[i].length;
}
}
var buffer = new Buffer(totalLength);
var pos = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
for (var j = 0; j < buf.length; j++) {
buffer[pos++] = buf[j];
}
}
return buffer;
};
module.exports = {
Buffer: Buffer,
SlowBuffer: Buffer,
kMaxLength: 2147483647,
constants: {
MAX_LENGTH: 2147483647,
MAX_STRING_LENGTH: 536870888
}
};
"#
}
"stream" => {
r#"
// Simplified Stream implementation
function Readable() {}
Readable.prototype.on = function(event, listener) {
this._events = this._events || {};
this._events[event] = this._events[event] || [];
this._events[event].push(listener);
return this;
};
Readable.prototype.emit = function(event) {
if (!this._events || !this._events[event]) return false;
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < this._events[event].length; i++) {
this._events[event][i].apply(this, args);
}
return true;
};
Readable.prototype.pipe = function(destination) {
this.on('data', function(chunk) {
destination.write(chunk);
});
this.on('end', function() {
destination.end();
});
return destination;
};
function Writable() {}
Writable.prototype.on = Readable.prototype.on;
Writable.prototype.emit = Readable.prototype.emit;
Writable.prototype.write = function() { return true; };
Writable.prototype.end = function() {};
function Transform() {}
Transform.prototype = Object.create(Readable.prototype);
Transform.prototype.constructor = Transform;
module.exports = {
Readable: Readable,
Writable: Writable,
Transform: Transform,
PassThrough: Transform
};
"#
}
"events" => {
r#"
// Enhanced EventEmitter implementation
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
EventEmitter.prototype.setMaxListeners = function(n) {
if (typeof n !== 'number' || n < 0)
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
if (type === 'error') {
if (!this._events.error ||
(Array.isArray(this._events.error) && !this._events.error.length))
{
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
throw TypeError('Uncaught, unspecified "error" event');
}
}
}
handler = this._events[type];
if (!handler)
return false;
if (Array.isArray(handler)) {
handler = handler.slice();
args = Array.prototype.slice.call(arguments, 1);
for (i = 0, len = handler.length; i < len; i++)
handler[i].apply(this, args);
} else {
args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
return true;
};
EventEmitter.prototype.on = function(type, listener) {
if (typeof listener !== 'function')
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
this._events[type] = this._events[type] || [];
this._events[type].push(listener);
return this;
};
EventEmitter.prototype.once = function(type, listener) {
if (typeof listener !== 'function')
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
EventEmitter.prototype.removeListener = function(type, listener) {
if (typeof listener !== 'function')
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
var list = this._events[type];
var length = list.length;
var position = -1;
for (var i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener))
{
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1)
list.length = 0;
else
list.splice(position, 1);
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
module.exports = EventEmitter;
"#
}
"crypto" => {
r#"
module.exports = {
createHash: function() { return { update: function() { return this; }, digest: function() { return ''; } }; },
randomBytes: function() { return new Uint8Array(0); }
};
"#
}
"url" => {
r#"
module.exports = {
parse: function(u) { return { href: u, pathname: u }; },
format: function(o) { return o.href || o.pathname || ''; }
};
"#
}
"querystring" => {
r#"
module.exports = {
parse: function() { return {}; },
stringify: function() { return ''; }
};
"#
}
"assert" => {
r#"
module.exports = {
ok: function(v) { if (!v) throw new Error('Assertion failed'); },
equal: function(a,b) { if (a !== b) throw new Error('Assertion failed'); },
strictEqual: function(a,b) { if (a !== b) throw new Error('Assertion failed'); }
};
"#
}
"constants" => {
r#"
module.exports = {
ERR_NO_CLEAR: false,
O_RDONLY: 0,
O_WRONLY: 1,
O_RDWR: 2,
S_IFMT: 61440,
S_IFREG: 32768,
S_IFDIR: 16384,
S_IFCHR: 8192,
S_IFBLK: 24576,
S_IFIFO: 4096,
S_IFLNK: 40960,
S_IFSOCK: 49152
};
"#
}
"http" => {
r#"
// Simplified HTTP module
var EventEmitter = require('events');
function createServer() {
return new EventEmitter();
}
function request() {
return new EventEmitter();
}
module.exports = {
createServer: createServer,
request: request,
get: function(url, cb) {
// Mock implementation
setTimeout(function() { cb(null, { statusCode: 200 }, ''); }, 100);
}
};
"#
}
"https" => {
r#"
// Simplified HTTPS module
var http = require('http');
module.exports = {
request: http.request,
get: http.get,
createServer: http.createServer
};
"#
}
"timers" => {
r#"
// Enhanced Timers module
var timers = {};
function setTimeout(callback, delay) {
if (typeof callback !== 'function') {
callback = function() {};
}
delay = delay || 0;
return globalThis.setTimeout(callback, delay);
}
function clearTimeout(timeoutId) {
return globalThis.clearTimeout(timeoutId);
}
function setInterval(callback, delay) {
if (typeof callback !== 'function') {
callback = function() {};
}
delay = delay || 0;
return globalThis.setInterval(callback, delay);
}
function clearInterval(intervalId) {
return globalThis.clearInterval(intervalId);
}
function setImmediate(callback) {
if (typeof callback !== 'function') {
callback = function() {};
}
return setTimeout(callback, 0);
}
function clearImmediate(immediateId) {
return clearTimeout(immediateId);
}
module.exports = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval,
setImmediate: setImmediate,
clearImmediate: clearImmediate
};
"#
}
"process" => {
r#"
// Process module (already implemented in runtime)
module.exports = global.process || {};
"#
}
_ => {
r#"
// Default stub for unknown modules
module.exports = {};
"#
}
}
}