|
3992 | 3992 | MessageChannel: globalThis.MessageChannel, |
3993 | 3993 | MessageEvent: globalThis.MessageEvent, |
3994 | 3994 | }; |
3995 | | - const moduleCompat = { |
| 3995 | + // Minimal readline implementation for sandbox compatibility. |
| 3996 | + // Supports createInterface with input/output streams, question(), and close(). |
| 3997 | + const readlineCompat = { |
| 3998 | + createInterface: function createInterface(opts) { |
| 3999 | + const input = opts && opts.input ? opts.input : (typeof process !== 'undefined' ? process.stdin : null); |
| 4000 | + const output = opts && opts.output ? opts.output : (typeof process !== 'undefined' ? process.stdout : null); |
| 4001 | + const listeners = {}; |
| 4002 | + const rl = { |
| 4003 | + input: input, |
| 4004 | + output: output, |
| 4005 | + terminal: false, |
| 4006 | + closed: false, |
| 4007 | + on: function(event, handler) { (listeners[event] = listeners[event] || []).push(handler); return rl; }, |
| 4008 | + once: function(event, handler) { |
| 4009 | + const wrapper = function() { rl.off(event, wrapper); handler.apply(this, arguments); }; |
| 4010 | + return rl.on(event, wrapper); |
| 4011 | + }, |
| 4012 | + off: function(event, handler) { |
| 4013 | + if (listeners[event]) listeners[event] = listeners[event].filter(function(h) { return h !== handler; }); |
| 4014 | + return rl; |
| 4015 | + }, |
| 4016 | + removeListener: function(event, handler) { return rl.off(event, handler); }, |
| 4017 | + emit: function(event) { |
| 4018 | + const args = Array.prototype.slice.call(arguments, 1); |
| 4019 | + (listeners[event] || []).forEach(function(h) { h.apply(null, args); }); |
| 4020 | + return rl; |
| 4021 | + }, |
| 4022 | + close: function() { |
| 4023 | + if (!rl.closed) { rl.closed = true; rl.emit('close'); } |
| 4024 | + }, |
| 4025 | + question: function(query, cb) { |
| 4026 | + if (output && output.write) output.write(query); |
| 4027 | + // Collect one line from input |
| 4028 | + if (input && input.once) { |
| 4029 | + var buf = ''; |
| 4030 | + var onData = function(chunk) { |
| 4031 | + buf += (typeof chunk === 'string' ? chunk : new TextDecoder().decode(chunk)); |
| 4032 | + var idx = buf.indexOf('\n'); |
| 4033 | + if (idx !== -1) { |
| 4034 | + input.removeListener('data', onData); |
| 4035 | + cb(buf.slice(0, idx)); |
| 4036 | + } |
| 4037 | + }; |
| 4038 | + input.on('data', onData); |
| 4039 | + } else { |
| 4040 | + cb(''); |
| 4041 | + } |
| 4042 | + }, |
| 4043 | + prompt: function() { if (output && output.write) output.write('> '); }, |
| 4044 | + setPrompt: function() {}, |
| 4045 | + pause: function() { return rl; }, |
| 4046 | + resume: function() { return rl; }, |
| 4047 | + write: function() {}, |
| 4048 | + [Symbol.asyncIterator]: function() { |
| 4049 | + var lines = []; |
| 4050 | + var resolve = null; |
| 4051 | + var done = false; |
| 4052 | + if (input) { |
| 4053 | + input.on('data', function(chunk) { |
| 4054 | + var text = typeof chunk === 'string' ? chunk : new TextDecoder().decode(chunk); |
| 4055 | + var parts = text.split('\n'); |
| 4056 | + for (var i = 0; i < parts.length - 1; i++) { |
| 4057 | + lines.push(parts[i]); |
| 4058 | + if (resolve) { resolve(); resolve = null; } |
| 4059 | + } |
| 4060 | + }); |
| 4061 | + input.on('end', function() { done = true; if (resolve) { resolve(); resolve = null; } }); |
| 4062 | + } |
| 4063 | + return { |
| 4064 | + next: function() { |
| 4065 | + if (lines.length > 0) return Promise.resolve({ value: lines.shift(), done: false }); |
| 4066 | + if (done) return Promise.resolve({ value: undefined, done: true }); |
| 4067 | + return new Promise(function(r) { resolve = r; }).then(function() { |
| 4068 | + if (lines.length > 0) return { value: lines.shift(), done: false }; |
| 4069 | + return { value: undefined, done: true }; |
| 4070 | + }); |
| 4071 | + } |
| 4072 | + }; |
| 4073 | + } |
| 4074 | + }; |
| 4075 | + return rl; |
| 4076 | + }, |
| 4077 | + promises: { |
| 4078 | + createInterface: function createInterface(opts) { |
| 4079 | + return readlineCompat.createInterface(opts); |
| 4080 | + }, |
| 4081 | + }, |
| 4082 | + }; |
| 4083 | + const moduleCompat = { |
3996 | 4084 | worker_threads: workerThreadsCompat, |
3997 | 4085 | 'node:worker_threads': workerThreadsCompat, |
| 4086 | + readline: readlineCompat, |
| 4087 | + 'node:readline': readlineCompat, |
3998 | 4088 | }; |
3999 | 4089 | let stub = null; |
4000 | 4090 | stub = new Proxy({}, { |
|
0 commit comments