import { initializeDebugEnv } from 'ext:deno_node/internal/util/debuglog.ts'
const PATH_TRAILING_SLASH_REGEX = /\/$/
const MULTIPLE_SLASHES_REGEX = /\/{2,}/g
const COMMAND_ARGS_REGEX = /(?:[^\s"']|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')+/g
const QUOTE_TRIM_REGEX = /^["']|["']$/g
const FORMAT_SPECIFIER_REGEX = /%[sdj%]/g
initializeDebugEnv('rari')
if (!globalThis.process) {
globalThis.process = {
env: {},
cwd: () => {
try {
return globalThis.Deno?.cwd() || '/'
}
catch {
return '/'
}
},
nextTick: fn => setTimeout(fn, 0),
platform: (() => {
try {
const os = globalThis.Deno?.build?.os
if (os === 'darwin')
return 'darwin'
if (os === 'linux')
return 'linux'
if (os === 'windows')
return 'win32'
return 'linux'
}
catch {
return 'linux'
}
})(),
arch: (() => {
try {
const arch = globalThis.Deno?.build?.arch
if (arch === 'x86_64')
return 'x64'
if (arch === 'aarch64')
return 'arm64'
return 'x64'
}
catch {
return 'x64'
}
})(),
version: 'v20.0.0',
versions: {
node: '20.0.0',
v8: '11.0.0',
uv: '1.0.0',
zlib: '1.0.0',
modules: '108',
},
argv: ['node'],
execPath: '/usr/bin/node',
execArgv: [],
pid: 1,
ppid: 0,
title: 'node',
exit: (code = 0) => {
if (globalThis.Deno?.exit)
globalThis.Deno.exit(code)
},
kill: () => {},
memoryUsage: () => ({
rss: 0,
heapTotal: 0,
heapUsed: 0,
external: 0,
arrayBuffers: 0,
}),
uptime: () => 0,
hrtime: () => [0, 0],
binding: () => ({}),
stdout: {
write: data => console.warn(data),
isTTY: false,
},
stderr: {
write: data => console.error(data),
isTTY: false,
},
stdin: {
isTTY: false,
},
}
}
const fs = {
existsSync: (path) => {
try {
if (globalThis.Deno?.statSync) {
globalThis.Deno.statSync(path)
return true
}
return false
}
catch {
return false
}
},
readFileSync: (path, encoding = 'utf8') => {
try {
if (globalThis.Deno?.readTextFileSync)
return globalThis.Deno.readTextFileSync(path)
throw new Error('readFileSync not available')
}
catch (error) {
throw new Error(`Cannot read file ${path}: ${error.message}`)
}
},
writeFileSync: (path, data, encoding = 'utf8') => {
try {
if (globalThis.Deno?.writeTextFileSync)
return globalThis.Deno.writeTextFileSync(path, data)
throw new Error('writeFileSync not available')
}
catch (error) {
throw new Error(`Cannot write file ${path}: ${error.message}`)
}
},
readFile: (path, encoding, callback) => {
if (typeof encoding === 'function') {
callback = encoding
}
try {
if (globalThis.Deno?.readTextFile) {
globalThis.Deno.readTextFile(path).then(
data => callback(null, data),
err => callback(err),
)
}
else {
callback(new Error('readFile not available'))
}
}
catch (error) {
callback(error)
}
},
writeFile: (path, data, encoding, callback) => {
if (typeof encoding === 'function') {
callback = encoding
}
try {
if (globalThis.Deno?.writeTextFile) {
globalThis.Deno.writeTextFile(path, data).then(
() => callback(null),
err => callback(err),
)
}
else {
callback(new Error('writeFile not available'))
}
}
catch (error) {
callback(error)
}
},
promises: {
readFile: async (path, encoding = 'utf8') => {
try {
if (globalThis.Deno?.readTextFile)
return await globalThis.Deno.readTextFile(path)
throw new Error('readFile not available')
}
catch (error) {
throw new Error(`Cannot read file ${path}: ${error.message}`)
}
},
writeFile: async (path, data, encoding = 'utf8') => {
try {
if (globalThis.Deno?.writeTextFile)
return await globalThis.Deno.writeTextFile(path, data)
throw new Error('writeFile not available')
}
catch (error) {
throw new Error(`Cannot write file ${path}: ${error.message}`)
}
},
},
}
const path = {
join: (...paths) => {
return paths.filter(Boolean).join('/').replace(MULTIPLE_SLASHES_REGEX, '/')
},
resolve: (...paths) => {
let resolved = ''
for (let i = paths.length - 1; i >= 0; i--) {
const segment = paths[i]
if (segment) {
resolved = `${segment}/${resolved}`
if (segment.startsWith('/'))
break
}
}
return resolved.replace(MULTIPLE_SLASHES_REGEX, '/').replace(PATH_TRAILING_SLASH_REGEX, '') || '/'
},
dirname: (path) => {
const parts = path.split('/')
parts.pop()
return parts.join('/') || '/'
},
basename: (path, ext) => {
let base = path.split('/').pop() || ''
if (ext && base.endsWith(ext))
base = base.slice(0, -ext.length)
return base
},
extname: (path) => {
const base = path.split('/').pop() || ''
const dot = base.lastIndexOf('.')
return dot > 0 ? base.slice(dot) : ''
},
relative: (from, to) => {
const fromParts = from.split('/').filter(Boolean)
const toParts = to.split('/').filter(Boolean)
let commonLength = 0
const minLength = Math.min(fromParts.length, toParts.length)
for (let i = 0; i < minLength; i++) {
if (fromParts[i] === toParts[i])
commonLength++
else
break
}
const upSegments = Array.from({ length: fromParts.length - commonLength }).fill('..')
const remaining = toParts.slice(commonLength)
const result = [...upSegments, ...remaining].join('/')
return result || '.'
},
isAbsolute: (path) => {
return path.startsWith('/')
},
sep: '/',
delimiter: ':',
posix: {
join: (...paths) => paths.filter(Boolean).join('/').replace(MULTIPLE_SLASHES_REGEX, '/'),
resolve: (...paths) => {
let resolved = ''
for (let i = paths.length - 1; i >= 0; i--) {
const segment = paths[i]
if (segment) {
resolved = `${segment}/${resolved}`
if (segment.startsWith('/'))
break
}
}
return resolved.replace(MULTIPLE_SLASHES_REGEX, '/').replace(PATH_TRAILING_SLASH_REGEX, '') || '/'
},
dirname: (path) => {
const parts = path.split('/')
parts.pop()
return parts.join('/') || '/'
},
basename: (path, ext) => {
let base = path.split('/').pop() || ''
if (ext && base.endsWith(ext))
base = base.slice(0, -ext.length)
return base
},
extname: (path) => {
const base = path.split('/').pop() || ''
const dot = base.lastIndexOf('.')
return dot > 0 ? base.slice(dot) : ''
},
relative: (from, to) => {
const fromParts = from.split('/').filter(Boolean)
const toParts = to.split('/').filter(Boolean)
let commonLength = 0
const minLength = Math.min(fromParts.length, toParts.length)
for (let i = 0; i < minLength; i++) {
if (fromParts[i] === toParts[i])
commonLength++
else
break
}
const upSegments = Array.from({ length: fromParts.length - commonLength }).fill('..')
const remaining = toParts.slice(commonLength)
const result = [...upSegments, ...remaining].join('/')
return result || '.'
},
isAbsolute: (path) => {
return path.startsWith('/')
},
sep: '/',
delimiter: ':',
},
}
const crypto = {
createHash: (algorithm) => {
if (globalThis.crypto?.subtle) {
return {
update: (data) => {
return {
digest: (encoding) => {
return `hash_${btoa(data).slice(0, 32)}`
},
}
},
}
}
throw new Error('crypto.createHash not available')
},
randomBytes: (size) => {
if (globalThis.crypto?.getRandomValues)
return globalThis.crypto.getRandomValues(new Uint8Array(size))
throw new Error('crypto.randomBytes not available')
},
randomUUID: () => {
if (globalThis.crypto?.randomUUID)
return globalThis.crypto.randomUUID()
throw new Error('crypto.randomUUID not available')
},
}
const util = {
inspect: (obj, options = {}) => {
try {
return JSON.stringify(obj, null, options.depth || 2)
}
catch {
return String(obj)
}
},
format: (f, ...args) => {
let index = 0
const str = String(f).replace(FORMAT_SPECIFIER_REGEX, (x) => {
if (x === '%%')
return '%'
if (index >= args.length)
return x
switch (x) {
case '%s':
return String(args[index++])
case '%d':
return Number(args[index++])
case '%j':
try {
return JSON.stringify(args[index++])
}
catch {
return '[Circular]'
}
default:
return x
}
})
return str
},
promisify: (fn) => {
return function (...args) {
return new Promise((resolve, reject) => {
fn.call(this, ...args, (err, result) => {
if (err)
reject(err)
else
resolve(result)
})
})
}
},
}
const os = {
platform: () => {
try {
const platform = globalThis.Deno?.build?.os
if (platform === 'darwin')
return 'darwin'
if (platform === 'linux')
return 'linux'
if (platform === 'windows')
return 'win32'
return 'linux'
}
catch {
return 'linux'
}
},
arch: () => {
try {
const arch = globalThis.Deno?.build?.arch
if (arch === 'x86_64')
return 'x64'
if (arch === 'aarch64')
return 'arm64'
return 'x64'
}
catch {
return 'x64'
}
},
cpus: () => {
try {
return globalThis.navigator?.hardwareConcurrency || 4
}
catch {
return 4
}
},
homedir: () => {
try {
return (
globalThis.Deno?.env?.get('HOME')
|| globalThis.Deno?.env?.get('USERPROFILE')
|| '/'
)
}
catch {
return '/'
}
},
tmpdir: () => {
try {
return (
globalThis.Deno?.env?.get('TMPDIR')
|| globalThis.Deno?.env?.get('TMP')
|| '/tmp'
)
}
catch {
return '/tmp'
}
},
endianness: () => 'LE',
EOL: '\n',
}
const Buffer = globalThis.Buffer || {
from: (data, encoding = 'utf8') => {
if (typeof data === 'string')
return new TextEncoder().encode(data)
return new Uint8Array(data)
},
alloc: (size, fill = 0) => {
const buf = new Uint8Array(size)
buf.fill(fill)
return buf
},
isBuffer: (obj) => {
return obj instanceof Uint8Array
},
}
const EventEmitter = class {
constructor() {
this._events = {}
}
on(event, listener) {
if (!this._events[event])
this._events[event] = []
this._events[event].push(listener)
return this
}
emit(event, ...args) {
if (!this._events[event])
return false
this._events[event].forEach((listener) => {
try {
listener.apply(this, args)
}
catch (error) {
console.error('EventEmitter error:', error)
}
})
return true
}
removeListener(event, listener) {
if (!this._events[event])
return this
this._events[event] = this._events[event].filter(l => l !== listener)
return this
}
off(event, listener) {
return this.removeListener(event, listener)
}
}
const nodeModules = new Map([
['node:process', globalThis.process],
['process', globalThis.process],
['node:fs', fs],
['fs', fs],
['node:fs/promises', fs.promises],
['fs/promises', fs.promises],
['node:path', path],
['path', path],
['node:crypto', crypto],
['crypto', crypto],
['node:util', util],
['util', util],
['node:os', os],
['os', os],
['node:buffer', { Buffer }],
['buffer', { Buffer }],
['node:events', { EventEmitter }],
['events', { EventEmitter }],
['node:stream', {
Stream: EventEmitter,
Readable: EventEmitter,
Writable: EventEmitter,
Transform: EventEmitter,
PassThrough: EventEmitter,
}],
['stream', {
Stream: EventEmitter,
Readable: EventEmitter,
Writable: EventEmitter,
Transform: EventEmitter,
PassThrough: EventEmitter,
}],
[
'node:url',
{ URL: globalThis.URL, URLSearchParams: globalThis.URLSearchParams },
],
[
'url',
{ URL: globalThis.URL, URLSearchParams: globalThis.URLSearchParams },
],
[
'node:querystring',
{
parse: (str) => {
const params = new URLSearchParams(str)
const result = {}
for (const [key, value] of params)
result[key] = value
return result
},
stringify: (obj) => {
return new URLSearchParams(obj).toString()
},
},
],
[
'querystring',
{
parse: (str) => {
const params = new URLSearchParams(str)
const result = {}
for (const [key, value] of params)
result[key] = value
return result
},
stringify: (obj) => {
return new URLSearchParams(obj).toString()
},
},
],
[
'node:timers',
{
setTimeout: globalThis.setTimeout,
clearTimeout: globalThis.clearTimeout,
setInterval: globalThis.setInterval,
clearInterval: globalThis.clearInterval,
setImmediate: fn => setTimeout(fn, 0),
clearImmediate: clearTimeout,
},
],
[
'timers',
{
setTimeout: globalThis.setTimeout,
clearTimeout: globalThis.clearTimeout,
setInterval: globalThis.setInterval,
clearInterval: globalThis.clearInterval,
setImmediate: fn => setTimeout(fn, 0),
clearImmediate: clearTimeout,
},
],
[
'node:assert',
{
ok: (value, message) => {
if (!value)
throw new Error(message || 'Assertion failed')
},
equal: (actual, expected, message) => {
if (actual !== expected)
throw new Error(message || `Expected ${expected}, got ${actual}`)
},
deepEqual: (actual, expected, message) => {
if (JSON.stringify(actual) !== JSON.stringify(expected))
throw new Error(message || 'Deep equality assertion failed')
},
},
],
[
'assert',
{
ok: (value, message) => {
if (!value)
throw new Error(message || 'Assertion failed')
},
equal: (actual, expected, message) => {
if (actual !== expected)
throw new Error(message || `Expected ${expected}, got ${actual}`)
},
deepEqual: (actual, expected, message) => {
if (JSON.stringify(actual) !== JSON.stringify(expected))
throw new Error(message || 'Deep equality assertion failed')
},
},
],
[
'node:child_process',
{
spawn: () => {
console.warn('child_process.spawn is not supported')
return { on: () => {}, stdout: { on: () => {} }, stderr: { on: () => {} } }
},
exec: (cmd, cb) => {
console.warn('child_process.exec is not supported')
if (cb)
cb(new Error('Not supported'), '', '')
},
execSync: (cmd, options = {}) => {
const parts = cmd.match(COMMAND_ARGS_REGEX) || []
const command = parts[0]
const args = parts.slice(1).map(arg => arg.replace(QUOTE_TRIM_REGEX, ''))
const denoCmd = new Deno.Command(command, {
args,
cwd: options.cwd,
stdout: 'piped',
stderr: 'piped',
})
const { stdout, stderr, success } = denoCmd.outputSync()
if (!success && options.stdio !== 'ignore') {
const error = new Error(`Command failed: ${cmd}`)
error.stderr = new TextDecoder().decode(stderr)
throw error
}
const output = new TextDecoder().decode(stdout)
return options.encoding === 'utf-8' || options.encoding === 'utf8' ? output : Buffer.from(stdout)
},
},
],
[
'child_process',
{
spawn: () => {
console.warn('child_process.spawn is not supported')
return { on: () => {}, stdout: { on: () => {} }, stderr: { on: () => {} } }
},
exec: (cmd, cb) => {
console.warn('child_process.exec is not supported')
if (cb)
cb(new Error('Not supported'), '', '')
},
execSync: (cmd, options = {}) => {
const parts = cmd.match(COMMAND_ARGS_REGEX) || []
const command = parts[0]
const args = parts.slice(1).map(arg => arg.replace(QUOTE_TRIM_REGEX, ''))
const denoCmd = new Deno.Command(command, {
args,
cwd: options.cwd,
stdout: 'piped',
stderr: 'piped',
})
const { stdout, stderr, success } = denoCmd.outputSync()
if (!success && options.stdio !== 'ignore') {
const error = new Error(`Command failed: ${cmd}`)
error.stderr = new TextDecoder().decode(stderr)
throw error
}
const output = new TextDecoder().decode(stdout)
return options.encoding === 'utf-8' || options.encoding === 'utf8' ? output : Buffer.from(stdout)
},
},
],
[
'node:tty',
{
isatty: () => false,
ReadStream: class {},
WriteStream: class {},
},
],
[
'tty',
{
isatty: () => false,
ReadStream: class {},
WriteStream: class {},
},
],
[
'node:net',
{
createServer: () => {
console.warn('net.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
connect: () => {
console.warn('net.connect is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'net',
{
createServer: () => {
console.warn('net.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
connect: () => {
console.warn('net.connect is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'node:http',
{
createServer: () => {
console.warn('http.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
request: () => {
console.warn('http.request is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'http',
{
createServer: () => {
console.warn('http.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
request: () => {
console.warn('http.request is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'node:https',
{
createServer: () => {
console.warn('https.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
request: () => {
console.warn('https.request is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'https',
{
createServer: () => {
console.warn('https.createServer is not supported')
return { listen: () => {}, on: () => {} }
},
request: () => {
console.warn('https.request is not supported')
return { on: () => {}, write: () => {}, end: () => {} }
},
},
],
[
'node:zlib',
{
createGzip: () => ({ pipe: x => x, on: () => {} }),
createGunzip: () => ({ pipe: x => x, on: () => {} }),
},
],
[
'zlib',
{
createGzip: () => ({ pipe: x => x, on: () => {} }),
createGunzip: () => ({ pipe: x => x, on: () => {} }),
},
],
[
'node:readline',
{
createInterface: () => ({ on: () => {}, close: () => {} }),
},
],
[
'readline',
{
createInterface: () => ({ on: () => {}, close: () => {} }),
},
],
[
'node:module',
{
createRequire: () => globalThis.require,
builtinModules: ['fs', 'path', 'os', 'util', 'crypto', 'stream', 'buffer', 'events'],
},
],
[
'module',
{
createRequire: () => globalThis.require,
builtinModules: ['fs', 'path', 'os', 'util', 'crypto', 'stream', 'buffer', 'events'],
},
],
])
if (!globalThis['~node'])
globalThis['~node'] = {}
if (!globalThis['~node'].modules) {
globalThis['~node'].modules = nodeModules
}
if (globalThis.import) {
const originalImport = globalThis.import
globalThis.import = function (specifier) {
if (nodeModules.has(specifier)) {
return Promise.resolve({
default: nodeModules.get(specifier),
...nodeModules.get(specifier),
})
}
return originalImport.call(this, specifier).catch((error) => {
if (globalThis['~rari']?.runtimeState) {
globalThis['~rari'].runtimeState.import_errors.push({
specifier,
error: error.message,
timestamp: Date.now(),
})
}
throw new Error(`Failed to import ${specifier}: ${error.message}`)
})
}
}
if (!globalThis.Buffer)
globalThis.Buffer = Buffer
if (!globalThis.global)
globalThis.global = globalThis
if (!globalThis.require) {
globalThis.require = function (specifier) {
const nodeSpecifier = specifier.startsWith('node:') ? specifier : `node:${specifier}`
if (nodeModules.has(nodeSpecifier))
return nodeModules.get(nodeSpecifier)
if (nodeModules.has(specifier))
return nodeModules.get(specifier)
throw new Error(`Cannot find module '${specifier}'`)
}
globalThis.require.resolve = function (specifier) {
return specifier
}
}