Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

run-pty

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

run-pty - npm Package Compare versions

Comparing version 2.3.0-beta.2 to 2.3.0-beta.3

2

package.json
{
"name": "run-pty",
"version": "2.3.0-beta.2",
"version": "2.3.0-beta.3",
"author": "Simon Lydell",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -74,2 +74,3 @@ #!/usr/bin/env node

const RESET_COLOR = "\x1B[m";
const RESET_COLOR_REGEX = /(\x1B\[0?m)/;
const CLEAR = IS_WINDOWS ? "\x1B[2J\x1B[0f" : "\x1B[2J\x1B[3J\x1B[H";

@@ -132,4 +133,9 @@ const CLEAR_RIGHT = "\x1B[K";

*/
const invert = (string) =>
NO_COLOR ? string : `\x1B[7m${string}${RESET_COLOR}`;
const invert = (string) => {
const inverted = string
.split(RESET_COLOR_REGEX)
.map((part, index) => (index % 2 === 0 ? `\x1B[7m${part}` : part))
.join("");
return NO_COLOR ? string : `${inverted}${RESET_COLOR}`;
};

@@ -140,6 +146,6 @@ /**

*/
const shortcut = (string, { pad = true, highlight = false } = {}) =>
dim(NO_COLOR && highlight ? "<" : "[") +
bold(highlight ? invert(string) : string) +
dim(NO_COLOR && highlight ? ">" : "]") +
const shortcut = (string, { pad = true } = {}) =>
dim("[") +
bold(string) +
dim("]") +
(pad ? " ".repeat(Math.max(0, KEYS.kill.length - string.length)) : "");

@@ -226,15 +232,14 @@

const drawDashboardCommandLines = (commands, width, cursorIndex) => {
const lines = commands.map((command, index) => {
const lines = commands.map((command) => {
const [icon, status] = statusText(command.status, command.statusFromRules);
return {
label: shortcut(command.label || " ", {
pad: false,
highlight: index === cursorIndex,
}),
label: shortcut(command.label || " ", { pad: false }),
icon,
status,
title: command.title,
title: command.titleWithGraphicRenditions,
};
});
const separator = " ";
const widestStatus = Math.max(

@@ -245,4 +250,3 @@ 0,

return lines.map(({ label, icon, status, title }) => {
const separator = " ";
return lines.map(({ label, icon, status, title }, index) => {
const start = truncate(`${label}${separator}${icon}`, width);

@@ -260,6 +264,12 @@ const startLength =

removeGraphicRenditions(truncatedEnd).length;
const finalEnd =
index === cursorIndex
? NO_COLOR
? `${separator.slice(0, -1)}→${truncatedEnd}`
: `${separator}${invert(truncatedEnd)}`
: `${separator}${truncatedEnd}`;
return {
line: `${start}${RESET_COLOR}${cursorHorizontalAbsolute(
startLength + 1
)}${CLEAR_RIGHT}${separator}${truncatedEnd}${RESET_COLOR}`,
)}${CLEAR_RIGHT}${finalEnd}${RESET_COLOR}`,
length,

@@ -316,4 +326,3 @@ };

const cwdText = (command) =>
path.resolve(command.cwd) === process.cwd() ||
command.cwd === removeGraphicRenditions(command.title)
path.resolve(command.cwd) === process.cwd() || command.cwd === command.title
? ""

@@ -397,4 +406,7 @@ : `${folder}${EMOJI_WIDTH_FIX} ${dim(command.cwd)}\n`;

// eslint-disable-next-line no-control-regex
const GRAPHIC_RENDITIONS = /(\x1B\[(?:\d+(?:;\d+)*)?m)/g;
const WINDOWS_HACK = IS_WINDOWS ? "\\0" : "";
const EMPTY_LAST_LINE = RegExp(
`(?:^|[${WINDOWS_HACK}\\r\\n])(?:[^\\S\\r\\n]|${GRAPHIC_RENDITIONS.source})*$`
);

@@ -769,2 +781,3 @@ /**

label: string,
focusOnlyCommand: boolean,
commandDescription: CommandDescription,

@@ -777,2 +790,3 @@ onData: (data: string, statusFromRulesChanged: boolean) => undefined,

label,
focusOnlyCommand,
commandDescription: {

@@ -793,6 +807,9 @@ title,

this.cwd = cwd;
this.title = title;
this.title = removeGraphicRenditions(title);
this.titleWithGraphicRenditions = title;
this.formattedCommandWithTitle =
title === formattedCommand
? formattedCommand
: NO_COLOR
? `${removeGraphicRenditions(title)}: ${formattedCommand}`
: `${bold(`${title}${RESET_COLOR}:`)} ${formattedCommand}`;

@@ -811,9 +828,10 @@ this.onData = onData;

this.statusRules = statusRules;
this.start();
this.start({ isFocused: focusOnlyCommand });
}
/**
* @param {{ isFocused: boolean }} options
* @returns {void}
*/
start() {
start({ isFocused }) {
if (this.status.tag !== "Exit") {

@@ -836,2 +854,11 @@ throw new Error(

"/c",
...(!isFocused
? [
"node",
"-e",
cmdEscapeArg("process.stdout.write('\\0')"),
// "echo:",
"&&",
]
: []),
cmdEscapeMetaChars(this.file),

@@ -850,5 +877,5 @@ ...this.args.map(cmdEscapeArg),

if (IS_WINDOWS) {
// Needed when using `conptyInheritCursor`. Otherwise the spawned
// terminals hang and will not run their command.
if (IS_WINDOWS && !isFocused) {
// Needed when using `conptyInheritCursor`. Otherwise terminals spawned in
// the background hang and will not run their command until focused.
terminal.write("\x1B[1;1R");

@@ -1005,14 +1032,9 @@ }

const maybeNewline = /[\r\n][^\S\r\n]*$/.test(command.history) ? "" : "\n";
const maybeNewline = EMPTY_LAST_LINE.test(command.history) ? "" : "\n";
switch (command.status.tag) {
case "Running":
if (
command.history.endsWith("\n") ||
command.history.endsWith(`\n${RESET_COLOR}`)
) {
if (command.history.endsWith("\n")) {
process.stdout.write(
RESET_COLOR +
maybeNewline +
runningText(command.status.terminal.pid)
RESET_COLOR + runningText(command.status.terminal.pid)
);

@@ -1068,5 +1090,8 @@ }

*/
const switchToCommand = (index) => {
const switchToCommand = (index, { viaMouse = false } = {}) => {
const command = commands[index];
current = { tag: "Command", index };
if (viaMouse) {
cursorIndex = undefined;
}
printHistoryAndExtraText(command);

@@ -1076,30 +1101,7 @@ };

/**
* @param {number | undefined} index
* @returns {void}
*/
const switchToCommandAtCursor = () => {
if (cursorIndex !== undefined) {
const command = commands[cursorIndex];
current = { tag: "Command", index: cursorIndex };
printHistoryAndExtraText(command);
}
};
/**
* @param {number} delta
* @returns {void}
*/
const moveCursor = (delta) => {
if (cursorIndex === undefined) {
cursorIndex =
delta === 0
? undefined
: delta > 0
? delta - 1
: commands.length + delta;
} else {
cursorIndex = (cursorIndex + delta) % commands.length;
if (cursorIndex < 0) {
cursorIndex = commands.length + cursorIndex;
}
}
const setCursor = (index) => {
cursorIndex = index;
// Redraw dashboard.

@@ -1129,2 +1131,4 @@ switchToDashboard();

const focusOnlyCommand = commandDescriptions.length === 1;
/** @type {Array<Command>} */

@@ -1135,2 +1139,3 @@ const commands = commandDescriptions.map(

label: ALL_LABELS[index] || "",
focusOnlyCommand,
commandDescription,

@@ -1219,6 +1224,6 @@ onData: (data, statusFromRulesChanged) => {

commands,
cursorIndex,
switchToDashboard,
switchToCommand,
switchToCommandAtCursor,
moveCursor,
setCursor,
killAll,

@@ -1257,3 +1262,3 @@ printHistoryAndExtraText

if (commands.length === 1) {
if (focusOnlyCommand) {
switchToCommand(0);

@@ -1269,6 +1274,6 @@ } else {

* @param {Array<Command>} commands
* @param {number | undefined} cursorIndex
* @param {() => void} switchToDashboard
* @param {(index: number) => void} switchToCommand
* @param {() => void} switchToCommandAtCursor
* @param {(delta: number) => void} moveCursor
* @param {(index: number, options?: { viaMouse?: boolean }) => void} switchToCommand
* @param {(index: number | undefined) => void} setCursor
* @param {() => void} killAll

@@ -1282,6 +1287,6 @@ * @param {(command: Command) => void} printHistoryAndExtraText

commands,
cursorIndex,
switchToDashboard,
switchToCommand,
switchToCommandAtCursor,
moveCursor,
setCursor,
killAll,

@@ -1321,3 +1326,3 @@ printHistoryAndExtraText

case KEY_CODES.restart:
command.start();
command.start({ isFocused: true });
printHistoryAndExtraText(command);

@@ -1340,3 +1345,5 @@ return undefined;

case KEY_CODES.enterVim:
switchToCommandAtCursor();
if (cursorIndex !== undefined) {
switchToCommand(cursorIndex);
}
return undefined;

@@ -1347,3 +1354,7 @@

case KEY_CODES.upVim:
moveCursor(-1);
setCursor(
cursorIndex === undefined || cursorIndex === 0
? commands.length - 1
: cursorIndex - 1
);
return undefined;

@@ -1354,3 +1365,7 @@

case KEY_CODES.downVim:
moveCursor(1);
setCursor(
cursorIndex === undefined || cursorIndex === commands.length - 1
? 0
: cursorIndex + 1
);
return undefined;

@@ -1367,21 +1382,28 @@

const mouseupPosition = parseMouseup(data);
if (mouseupPosition !== undefined) {
const { x, y } = mouseupPosition;
const lines = drawDashboardCommandLines(
commands,
process.stdout.columns,
undefined
);
if (y >= 0 && y < lines.length) {
const max = Math.max(
...lines.map((otherLine) => otherLine.length)
);
if (x >= 0 && x < max) {
switchToCommand(y);
const mouseupPosition = parseMouse(data);
if (mouseupPosition === undefined) {
return undefined;
}
const index = getCommandIndexFromMousePosition(
commands,
mouseupPosition
);
switch (mouseupPosition.type) {
case "mousedown":
if (index !== undefined) {
setCursor(index);
}
return undefined;
case "mouseup": {
if (index !== undefined && index === cursorIndex) {
switchToCommand(index, { viaMouse: true });
} else if (cursorIndex !== undefined) {
setCursor(undefined);
}
return undefined;
}
}
return undefined;
}

@@ -1392,10 +1414,9 @@ }

// eslint-disable-next-line no-control-regex
const MOUSEUP_REGEX = /\x1B\[<0;(\d+);(\d+)m/;
const MOUSEUP_REGEX = /\x1B\[<0;(\d+);(\d+)([Mm])/;
/**
* @param {string} string
* @returns {{ x: number, y: number } | undefined}
* @returns {{ type: "mousedown" | "mouseup", x: number, y: number } | undefined}
*/
const parseMouseup = (string) => {
const parseMouse = (string) => {
const match = MOUSEUP_REGEX.exec(string);

@@ -1405,7 +1426,32 @@ if (match === null) {

}
const [, x, y] = match;
return { x: Number(x) - 1, y: Number(y) - 1 };
const [, x, y, type] = match;
return {
type: type === "M" ? "mousedown" : "mouseup",
x: Number(x) - 1,
y: Number(y) - 1,
};
};
/**
* @param {Array<Command>} commands
* @param {{ x: number, y: number }} mousePosition
*/
const getCommandIndexFromMousePosition = (commands, { x, y }) => {
const lines = drawDashboardCommandLines(
commands,
process.stdout.columns,
undefined
);
if (y >= 0 && y < lines.length) {
const line = lines[y];
if (x >= 0 && x < line.length) {
return y;
}
}
return undefined;
};
/**
* @returns {undefined}

@@ -1412,0 +1458,0 @@ */

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