New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

bun-repl

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bun-repl - npm Package Compare versions

Comparing version 1.0.3 to 1.1.0

src/replmanager.ts

5

package.json
{
"type": "module",
"name": "bun-repl",
"version": "1.0.3",
"version": "1.1.0",
"description": "Experimental unofficial REPL for Bun",

@@ -28,3 +28,4 @@ "main": "src/module/repl.ts",

"@swc/core": "^1.2.224",
"pretty-ms": "^8.0.0"
"pretty-ms": "^8.0.0",
"rustybun": "^0.1.2"
},

@@ -31,0 +32,0 @@ "devDependencies": {

14

README.md

@@ -23,6 +23,4 @@ # bun-repl [![GitHub version][github-image]][github-url] [![GitHub code size in bytes][size-image]][github-url] [![license][license-image]][license-url]

Press `↑`+`Enter` to travel up the execution history.
Press `↑` and `↓` to travel up or down the execution history.
Press `↓`+`Enter` to travel back down.
## Features

@@ -46,10 +44,4 @@

* Multi-line inputs are not supported.
* Reason: Same as below.
* Pressing `←` and `→` to traverse the input with the cursor is not supported.
* Reason: Same as below.
* The execution history is buggy to navigate and doesn't support backspacing past the history entry.
* Reason: Bun's current lack of support for event-based streams limits us to `prompt()`, which provides little to no control over the input as its being written. This also makes it impossible to intercept keypresses/combinations.
* There is a space between the execution history entry and your appended code.
* Reason: `prompt()` automatically inserts a space at the end, with no way to turn it off. Yes, quite annoying.
* To preserve lexically-scoped variables (`let` & `const`) across REPL runs, they need to be converted to `var`, which disrupts their behavior, especially `const`'s
* Reason: The library used for prompts (`rustybun`) doesn't support this.
* To preserve lexically-scoped variables (`let` & `const`) across REPL runs, they need to be converted to `var`, which disrupts their behavior, especially `const`'s (This also requires using non-strict mode)
* Reason: Usage of `eval()` which has its own lexical scope.

@@ -56,0 +48,0 @@

@@ -64,2 +64,7 @@ const colors = {

export default { ...colors, bg: bgColors };
function bool(bool: boolean, important: boolean = false) {
if (bool) return `${colors.greenBright}true${colors.reset}`;
else return `${important ? colors.redBright : colors.gray}false${colors.reset}`;
}
export default { ...colors, bg: bgColors, bool };

@@ -57,2 +57,8 @@ declare global {

interface PartialNPMResponse {
'dist-tags': {
latest: string
}
}
interface ImportMeta {

@@ -59,0 +65,0 @@ require: (moduleIdentifier: string) => unknown;

@@ -5,3 +5,4 @@ /* eslint-disable unicorn/custom-error-definition */

import $ from '../colors';
import util from 'util';
import bun from 'bun';
import { SafeInspect } from '../utils';

@@ -60,3 +61,3 @@ class NotImplementedError extends Error {

depth: 2,
colors: Bun.enableANSIColors,
colors: bun.enableANSIColors,
customInspect: true,

@@ -77,15 +78,16 @@ showProxy: true,

export const writer: REPLWriterFunction = function writer(val: any): string {
return util.inspect(val, (<REPLWriterFunction>writer).options);
};
writer.options = new Proxy(REPLWriterOptionsDefaults, {
set(target, p, value) {
console.warn(`${$.yellow+$.dim}(warning) repl.writer.options are currently not all fully respected by the REPL.${$.reset}`);
// @ts-expect-error Temporary warning Proxy
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
target[p] = value;
return true;
}
export const writer = function writer(val: any): string {
return (SafeInspect(val, (<REPLWriterFunction>writer).options) ?? bun.inspect(val));
} as REPLWriterFunction;
Object.defineProperty(writer, 'options', {
value: new Proxy(REPLWriterOptionsDefaults, {
set(target, p, value) {
console.warn(`${$.yellow+$.dim}(warning) repl.writer.options are currently not all fully respected by the REPL.${$.reset}`);
// @ts-expect-error Temporary warning Proxy
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
target[p] = value;
return true;
}
}), enumerable: true
});
}

@@ -92,0 +94,0 @@

@@ -10,7 +10,8 @@ #!/usr/bin/env bun

import Transpiler from './transpiler';
import REPLState from './replstate';
import REPLHistory from './replhistory';
import REPLManager from './replmanager';
import pkgjson from './pkgjson';
import { debuglog, IS_DEBUG } from './debug';
debuglog(process.argv);
const helpFlag = process.argv.includes('-h') || process.argv.includes('--help');

@@ -28,8 +29,2 @@ if (helpFlag) {

interface PartialNPMResponse {
'dist-tags': {
latest: string
}
}
if (process.argv.includes('--update')) {

@@ -51,22 +46,57 @@ console.log(`${$.dim}Checking for updates...${$.reset}`);

let evalFlag = process.argv.indexOf('-e');
if (evalFlag === -1) evalFlag = process.argv.indexOf('--eval');
let printFlag = process.argv.indexOf('-p');
if (printFlag === -1) printFlag = process.argv.indexOf('--print');
if (evalFlag !== -1 && printFlag !== -1) {
console.error(`bun-repl: Incompatible options "${$.whiteBright}--eval${$.red}" and "${$.whiteBright}--print${$.red}"`);
console.error(`For more information try ${$.whiteBright}--help${$.reset}`);
process.exit(0);
}
const singleshot = evalFlag !== -1 || printFlag !== -1;
const singleshotCode = process.argv.slice((evalFlag !== -1 ? evalFlag : printFlag) + 1).join(' ');
const validFlags = [
'-h', '--help', '-v', '--version', '--update', '--debug', '-e', '--eval', '-p', '--print'
] as const;
if (process.argv.length > 2) {
for (const arg of process.argv.slice(2)) {
if (['-e', '--eval', '-p', '--print'].includes(arg)) break;
if (validFlags.includes(arg as typeof validFlags[0])) continue;
console.error(`bun-repl: Unknown option "${$.whiteBright+arg+$.red}"`);
console.error(`For more information try ${$.whiteBright}--help${$.reset}`);
process.exit(0);
}
}
const realm = new ShadowRealm();
// Inject realm globals
await realm.execFile('./realm.mjs');
const replState = new REPLState();
const replHistory = new REPLHistory();
const repl = new REPLManager();
const transpiler = new Transpiler();
console.log(`Welcome to Bun.js ${process.version} (${process.revision ? 'canary-'+process.revision : 'release'})
Type ".help" for more information.`);
debuglog(`${$.dim}INFO: Debug mode enabled.${$.reset}`);
// Prepare realm environment
await realm.execFile('./realm.mjs');
MainLoop: for (;;) {
if (!singleshot) {
console.log(
`Welcome to Bun.js ${process.version} (${process.revision ? 'canary-' + process.revision : 'release'})\n` +
`Type ".help" for more information.`
);
debuglog(`${$.dim}INFO: Debug mode enabled.${$.reset}`);
}
let userInput = prompt(`>${replState.historyEntry ? ' ' + replState.historyEntry : ''}`)?.trim();
MainLoop: do {
const userInput = singleshot ? singleshotCode : repl.promptline();
if (!userInput) {
if (singleshot) {
console.error(`bun-repl: Option "${$.whiteBright+(evalFlag !== -1 ? '--eval' : '--print')+$.red}" requires a value.`);
console.error(`For more information try ${$.whiteBright}--help${$.reset}`);
process.exit(0);
} else continue;
}
if (userInput === 'undefined') {
console.log($.gray+userInput+$.reset);
continue;
}
userInput ??= replState.historyEntry ? '' : 'undefined';
if (replState.historyEntry) userInput = replState.historyEntry + userInput;
if (userInput.startsWith('.')) {
if (userInput.startsWith('.') && !singleshot) {
const command = userInput.slice(1).split(/[ \t]+/)[0];

@@ -79,3 +109,3 @@ switch (command) {

default:
console.error(`Unknown REPL command ".${command}", type ".help" for more information.`);
console.error(`Unknown REPL command "${$.whiteBright}.${command}${$.red}", type "${$.whiteBright}.help${$.red}" for more information.`);
continue MainLoop;

@@ -85,10 +115,3 @@ }

if (userInput.endsWith('\u001B[A')) { replState.historyEntry = replHistory.consume(); continue; }
if (userInput.endsWith('\u001B[B')) { replState.historyEntry = replHistory.unconsume(); continue; }
replState.historyEntry = '';
replHistory.add(userInput);
replHistory.resetPos();
let transpiled: string = transpiler.preAdjust(userInput);
let transpiled: string = transpiler.preprocess(userInput);
debuglog($.dim+'preprocess:', transpiled.trim()+$.reset);

@@ -103,3 +126,3 @@ try {

debuglog($.dim+'transpile:', transpiled.trim()+$.reset);
transpiled = transpiler.postAdjust(transpiled);
transpiled = transpiler.postprocess(transpiled);
debuglog($.dim+'postprocess:', transpiled.trim()+$.reset);

@@ -124,3 +147,3 @@

REPLGlobal.console.error('This is most likely a bug, please report it at ${pkgjson.bugs?.url ?? 'the project\'s GitHub repository'}');
} else REPLGlobal.console.log(val);
} else if (${!singleshot || printFlag !== -1}) REPLGlobal.console.log(val);
`);

@@ -132,14 +155,4 @@ } catch (error) {

}
}
} while (!singleshot);
function printHelp(): void {
console.log(`Commands:
.help = Print this message.
.info = Print REPL information.
.clear = Clear the screen.
.exit = Exit the REPL.
Press Ctrl+C or Ctrl+Z to forcefully terminate the REPL.`);
}
function printCLIHelp(): void {

@@ -149,19 +162,34 @@ console.log(`Usage: bun-repl [options]

Options:
-h, --help = Display this message.
-v, --version = Show installed bun-repl version.
--update = Check for bun-repl updates.
--debug = Print debug information while running.
-h, --help Display this message.
-v, --version Show installed bun-repl version.
-p, --print <...> Evaluates given code, prints result and exits.
-e, --eval <...> Evaluates given code and silently exits.
--update Check for bun-repl updates.
--debug Print debug information while running.
* Options with <...> as argument must be passed last.
Environment variables:
None`);
BUN_REPL_PROMPT A string to override the default "> " prompt with.
BUN_REPL_MODE Either "sloppy" or "strict" (Not implemented)`);
}
function printHelp(): void {
console.log(`Commands & keybinds:
.help Print this message.
.info Print REPL information.
.clear Clear the screen. ${$.gray}(Ctrl+L)${$.reset}
.exit Exit the REPL. ${$.gray}(Ctrl+C / Ctrl+D)${$.reset}`);
}
function printInfo(): void {
console.log(`bun-repl v${pkgjson.version}
Installed at: ${path.join(import.meta.dir, '..')}
Installed at: ${$.cyan+path.join(import.meta.dir, '..')+$.reset}
Bun version: ${process.version}
SWC version: ${swc.version as string}
Color mode: ${Bun.enableANSIColors}
Debug mode: ${IS_DEBUG}
Current session uptime: ${prettyms(performance.now())}`);
SWC version: v${swc.version as string}
Color mode: ${$.bool(Bun.enableANSIColors)}
Debug mode: ${$.bool(IS_DEBUG)}
Current session uptime: ${$.yellow+prettyms(performance.now())+$.reset}`);
}
process.exit(0); // Prevents a segfault when exiting

@@ -21,3 +21,3 @@ import swc from '@swc/core';

// REPL-specific adjustments needed for the code to work in a REPL context. (Ran before transpile)
preAdjust(code: string): string {
preprocess(code: string): string {
return code

@@ -44,3 +44,3 @@ .replace(/import(?:(?:(?:[ \n\t]+([^ *\n\t{},]+)[ \n\t]*(?:,|[ \n\t]+))?([ \n\t]*\{(?:[ \n\t]*[^ \n\t"'{}]+[ \n\t]*,?)+\})?[ \n\t]*)|[ \n\t]*\*[ \n\t]*as[ \n\t]+([^ \n\t{}]+)[ \n\t]+)from[ \n\t]*(?:['"])([^'"\n]+)(['"])/g,

// REPL-specific adjustments needed for the code to work in a REPL context. (Ran after transpile)
postAdjust(code: string): string {
postprocess(code: string): string {
return code

@@ -47,0 +47,0 @@ .replace(/(?:let|const) ([A-Za-z_$\d]+? ?=.)/g,

@@ -19,6 +19,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */

/**
* Safely call an object's method.
* Safely call a function on an object as the `this`.
* If an error occurs, just treat it as non-existent.
*/
export function SafeCall<F extends (...x: any[]) => any>(fn: F, thisArg: any, ...args: Parameters<F>): ReturnType<F> | undefined {
export function SafeThiscall<F extends (...x: any[]) => any>(fn: F, thisArg: any, ...args: Parameters<F>): ReturnType<F> | undefined {
try {

@@ -25,0 +25,0 @@ return fn?.apply?.(thisArg, args);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc