@lvce-editor/pty-host
Version:
Terminal process used in Lvce Editor.
1,672 lines (1,619 loc) • 73.1 kB
JavaScript
import debugModule from 'debug';
import { spawn } from 'node-pty';
import { Console } from 'node:console';
import { createWriteStream, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { fileURLToPath } from 'node:url';
import { Buffer } from 'node:buffer';
class CommandNotFoundError extends Error {
constructor(command) {
super(`Command not found ${command}`);
this.name = 'CommandNotFoundError';
}
}
const commands = Object.create(null);
const register = commandMap => {
Object.assign(commands, commandMap);
};
const getCommand = key => {
return commands[key];
};
const execute = (command, ...args) => {
const fn = getCommand(command);
if (!fn) {
throw new CommandNotFoundError(command);
}
return fn(...args);
};
const normalizeLine = line => {
if (line.startsWith('Error: ')) {
return line.slice('Error: '.length);
}
if (line.startsWith('VError: ')) {
return line.slice('VError: '.length);
}
return line;
};
const getCombinedMessage = (error, message) => {
const stringifiedError = normalizeLine(`${error}`);
if (message) {
return `${message}: ${stringifiedError}`;
}
return stringifiedError;
};
const NewLine$4 = '\n';
const getNewLineIndex$2 = (string, startIndex = undefined) => {
return string.indexOf(NewLine$4, startIndex);
};
const mergeStacks = (parent, child) => {
if (!child) {
return parent;
}
const parentNewLineIndex = getNewLineIndex$2(parent);
const childNewLineIndex = getNewLineIndex$2(child);
if (childNewLineIndex === -1) {
return parent;
}
const parentFirstLine = parent.slice(0, parentNewLineIndex);
const childRest = child.slice(childNewLineIndex);
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
if (parentFirstLine.includes(childFirstLine)) {
return parentFirstLine + childRest;
}
return child;
};
class VError extends Error {
constructor(error, message) {
const combinedMessage = getCombinedMessage(error, message);
super(combinedMessage);
this.name = 'VError';
if (error instanceof Error) {
this.stack = mergeStacks(this.stack, error.stack);
}
if (error.codeFrame) {
// @ts-ignore
this.codeFrame = error.codeFrame;
}
if (error.code) {
// @ts-ignore
this.code = error.code;
}
}
}
class AssertionError extends Error {
constructor(message) {
super(message);
this.name = 'AssertionError';
}
}
const Object$1 = 1;
const Number$1 = 2;
const Array$1 = 3;
const String$1 = 4;
const Boolean = 5;
const Function = 6;
const Null = 7;
const Unknown = 8;
const getType = value => {
switch (typeof value) {
case 'number':
return Number$1;
case 'function':
return Function;
case 'string':
return String$1;
case 'object':
if (value === null) {
return Null;
}
if (Array.isArray(value)) {
return Array$1;
}
return Object$1;
case 'boolean':
return Boolean;
default:
return Unknown;
}
};
const object = value => {
const type = getType(value);
if (type !== Object$1) {
throw new AssertionError('expected value to be of type object');
}
};
const number = value => {
const type = getType(value);
if (type !== Number$1) {
throw new AssertionError('expected value to be of type number');
}
};
const array = value => {
const type = getType(value);
if (type !== Array$1) {
throw new AssertionError('expected value to be of type array');
}
};
const string = value => {
const type = getType(value);
if (type !== String$1) {
throw new AssertionError('expected value to be of type string');
}
};
const isMessagePort = value => {
return value && value instanceof MessagePort;
};
const isMessagePortMain = value => {
return value && value.constructor && value.constructor.name === 'MessagePortMain';
};
const isOffscreenCanvas = value => {
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
};
const isInstanceOf = (value, constructorName) => {
return value?.constructor?.name === constructorName;
};
const isSocket = value => {
return isInstanceOf(value, 'Socket');
};
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
const isTransferrable = value => {
for (const fn of transferrables) {
if (fn(value)) {
return true;
}
}
return false;
};
const walkValue = (value, transferrables, isTransferrable) => {
if (!value) {
return;
}
if (isTransferrable(value)) {
transferrables.push(value);
return;
}
if (Array.isArray(value)) {
for (const item of value) {
walkValue(item, transferrables, isTransferrable);
}
return;
}
if (typeof value === 'object') {
for (const property of Object.values(value)) {
walkValue(property, transferrables, isTransferrable);
}
return;
}
};
const getTransferrables = value => {
const transferrables = [];
walkValue(value, transferrables, isTransferrable);
return transferrables;
};
const removeValues = (value, toRemove) => {
if (!value) {
return value;
}
if (Array.isArray(value)) {
const newItems = [];
for (const item of value) {
if (!toRemove.includes(item)) {
newItems.push(removeValues(item, toRemove));
}
}
return newItems;
}
if (typeof value === 'object') {
const newObject = Object.create(null);
for (const [key, property] of Object.entries(value)) {
if (!toRemove.includes(property)) {
newObject[key] = removeValues(property, toRemove);
}
}
return newObject;
}
return value;
};
// workaround for electron not supporting transferrable objects
// as parameters. If the transferrable object is a parameter, in electron
// only an empty objected is received in the main process
const fixElectronParameters = value => {
const transfer = getTransferrables(value);
const newValue = removeValues(value, transfer);
return {
newValue,
transfer
};
};
const getActualDataElectron = event => {
const {
data,
ports
} = event;
if (ports.length === 0) {
return data;
}
return {
...data,
params: [...ports, ...data.params]
};
};
const attachEvents = that => {
const handleMessage = (...args) => {
const data = that.getData(...args);
that.dispatchEvent(new MessageEvent('message', {
data
}));
};
that.onMessage(handleMessage);
const handleClose = event => {
that.dispatchEvent(new Event('close'));
};
that.onClose(handleClose);
};
class Ipc extends EventTarget {
constructor(rawIpc) {
super();
this._rawIpc = rawIpc;
attachEvents(this);
}
}
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
const ERR_MODULE_NOT_FOUND$1 = 'ERR_MODULE_NOT_FOUND';
const NewLine$3 = '\n';
const joinLines$2 = lines => {
return lines.join(NewLine$3);
};
const RE_AT$1 = /^\s+at/;
const RE_AT_PROMISE_INDEX$1 = /^\s*at async Promise.all \(index \d+\)$/;
const isNormalStackLine$1 = line => {
return RE_AT$1.test(line) && !RE_AT_PROMISE_INDEX$1.test(line);
};
const getDetails$1 = lines => {
const index = lines.findIndex(isNormalStackLine$1);
if (index === -1) {
return {
actualMessage: joinLines$2(lines),
rest: []
};
}
let lastIndex = index - 1;
while (++lastIndex < lines.length) {
if (!isNormalStackLine$1(lines[lastIndex])) {
break;
}
}
return {
actualMessage: lines[index - 1],
rest: lines.slice(index, lastIndex)
};
};
const splitLines$2 = lines => {
return lines.split(NewLine$3);
};
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
const isMessageCodeBlockStartIndex = line => {
return RE_MESSAGE_CODE_BLOCK_START.test(line);
};
const isMessageCodeBlockEndIndex = line => {
return RE_MESSAGE_CODE_BLOCK_END.test(line);
};
const getMessageCodeBlock = stderr => {
const lines = splitLines$2(stderr);
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
const relevantLines = lines.slice(startIndex, endIndex);
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
return relevantMessage;
};
const isModuleNotFoundMessage = line => {
return line.includes('[ERR_MODULE_NOT_FOUND]');
};
const getModuleNotFoundError = stderr => {
const lines = splitLines$2(stderr);
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
const message = lines[messageIndex];
return {
message,
code: ERR_MODULE_NOT_FOUND$1
};
};
const isModuleNotFoundError = stderr => {
if (!stderr) {
return false;
}
return stderr.includes('ERR_MODULE_NOT_FOUND');
};
const isModulesSyntaxError = stderr => {
if (!stderr) {
return false;
}
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
};
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
const isUnhelpfulNativeModuleError = stderr => {
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
};
const getNativeModuleErrorMessage = stderr => {
const message = getMessageCodeBlock(stderr);
return {
message: `Incompatible native node module: ${message}`,
code: E_INCOMPATIBLE_NATIVE_MODULE
};
};
const getModuleSyntaxError = () => {
return {
message: `ES Modules are not supported in electron`,
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
};
};
const getHelpfulChildProcessError = (stdout, stderr) => {
if (isUnhelpfulNativeModuleError(stderr)) {
return getNativeModuleErrorMessage(stderr);
}
if (isModulesSyntaxError(stderr)) {
return getModuleSyntaxError();
}
if (isModuleNotFoundError(stderr)) {
return getModuleNotFoundError(stderr);
}
const lines = splitLines$2(stderr);
const {
actualMessage,
rest
} = getDetails$1(lines);
return {
message: actualMessage,
code: '',
stack: rest
};
};
class IpcError extends VError {
// @ts-ignore
constructor(betterMessage, stdout = '', stderr = '') {
if (stdout || stderr) {
// @ts-ignore
const {
message,
code,
stack
} = getHelpfulChildProcessError(stdout, stderr);
const cause = new Error(message);
// @ts-ignore
cause.code = code;
cause.stack = stack;
super(cause, betterMessage);
} else {
super(betterMessage);
}
// @ts-ignore
this.name = 'IpcError';
// @ts-ignore
this.stdout = stdout;
// @ts-ignore
this.stderr = stderr;
}
}
const listen$b = ({
messagePort
}) => {
if (!isMessagePortMain(messagePort)) {
throw new IpcError('port must be of type MessagePortMain');
}
return messagePort;
};
const signal$c = messagePort => {
messagePort.start();
};
class IpcChildWithElectronMessagePort extends Ipc {
getData = getActualDataElectron;
send(message) {
this._rawIpc.postMessage(message);
}
sendAndTransfer(message) {
const {
newValue,
transfer
} = fixElectronParameters(message);
this._rawIpc.postMessage(newValue, transfer);
}
dispose() {
this._rawIpc.close();
}
onMessage(callback) {
this._rawIpc.on('message', callback);
}
onClose(callback) {
this._rawIpc.on('close', callback);
}
}
const wrap$j = messagePort => {
return new IpcChildWithElectronMessagePort(messagePort);
};
const IpcChildWithElectronMessagePort$1 = {
__proto__: null,
listen: listen$b,
signal: signal$c,
wrap: wrap$j
};
// @ts-ignore
const getUtilityProcessPortData = event => {
const {
data,
ports
} = event;
if (ports.length === 0) {
return data;
}
return {
...data,
params: [...ports, ...data.params]
};
};
const readyMessage = 'ready';
const listen$a = () => {
// @ts-ignore
const {
parentPort
} = process;
if (!parentPort) {
throw new Error('parent port must be defined');
}
return parentPort;
};
const signal$b = parentPort => {
parentPort.postMessage(readyMessage);
};
class IpcChildWithElectronUtilityProcess extends Ipc {
getData(event) {
return getUtilityProcessPortData(event);
}
send(message) {
this._rawIpc.postMessage(message);
}
sendAndTransfer(message) {
const {
newValue,
transfer
} = fixElectronParameters(message);
this._rawIpc.postMessage(newValue, transfer);
}
dispose() {
this._rawIpc.close();
}
onClose(callback) {
this._rawIpc.on('close', callback);
}
onMessage(callback) {
this._rawIpc.on('message', callback);
}
}
const wrap$i = parentPort => {
return new IpcChildWithElectronUtilityProcess(parentPort);
};
const IpcChildWithElectronUtilityProcess$1 = {
__proto__: null,
listen: listen$a,
signal: signal$b,
wrap: wrap$i
};
const getActualData = (message, handle) => {
if (handle) {
return {
...message,
params: [handle, ...message.params]
};
}
return message;
};
const getTransferrablesNode = value => {
const transferrables = getTransferrables(value);
if (transferrables.length === 0) {
throw new Error(`no transferrables found`);
}
return transferrables[0];
};
const listen$5 = async () => {
if (!process.send) {
throw new Error('process.send must be defined');
}
return process;
};
const signal$7 = process => {
process.send(readyMessage);
};
class IpcChildWithNodeForkedProcess extends Ipc {
getData(message, handle) {
return getActualData(message, handle);
}
onClose(callback) {
this._rawIpc.on('close', callback);
}
send(message) {
this._rawIpc.send(message);
}
onMessage(callback) {
this._rawIpc.on('message', callback);
}
sendAndTransfer(message) {
const transfer = getTransferrablesNode(message);
this._rawIpc.send(message, transfer);
}
dispose() {
// ignore
}
}
const wrap$d = process => {
return new IpcChildWithNodeForkedProcess(process);
};
const IpcChildWithNodeForkedProcess$1 = {
__proto__: null,
listen: listen$5,
signal: signal$7,
wrap: wrap$d
};
const Open = 2;
const Close = 3;
const addListener = (emitter, type, callback) => {
if ('addEventListener' in emitter) {
emitter.addEventListener(type, callback);
} else {
emitter.on(type, callback);
}
};
const removeListener = (emitter, type, callback) => {
if ('removeEventListener' in emitter) {
emitter.removeEventListener(type, callback);
} else {
emitter.off(type, callback);
}
};
const getFirstEvent = (eventEmitter, eventMap) => {
const {
resolve,
promise
} = Promise.withResolvers();
const listenerMap = Object.create(null);
const cleanup = value => {
for (const event of Object.keys(eventMap)) {
removeListener(eventEmitter, event, listenerMap[event]);
}
resolve(value);
};
for (const [event, type] of Object.entries(eventMap)) {
const listener = event => {
cleanup({
type,
event
});
};
addListener(eventEmitter, event, listener);
listenerMap[event] = listener;
}
return promise;
};
// @ts-ignore
const getFirstWebSocketEvent = async webSocket => {
// @ts-ignore
const {
WebSocket
} = await import('ws');
switch (webSocket.readyState) {
case WebSocket.OPEN:
return {
type: Open,
event: undefined
};
case WebSocket.CLOSED:
return {
type: Close,
event: undefined
};
}
// @ts-ignore
const {
type,
event
} = await getFirstEvent(webSocket, {
open: Open,
close: Close
});
return {
type,
event
};
};
// @ts-ignore
const isWebSocketOpen = async webSocket => {
// @ts-ignore
const {
WebSocket
} = await import('ws');
return webSocket.readyState === WebSocket.OPEN;
};
// @ts-ignore
const serialize = message => {
return JSON.stringify(message);
};
// @ts-ignore
const deserialize = message => {
return JSON.parse(message.toString());
};
// @ts-ignore
const handleUpgrade$1 = async (...args) => {
const module = await Promise.resolve().then(function () { return index; });
// @ts-ignore
return module.handleUpgrade(...args);
};
const listen$1$1 = async ({
request,
handle
}) => {
if (!request) {
throw new IpcError('request must be defined');
}
if (!handle) {
throw new IpcError('handle must be defined');
}
const webSocket = await handleUpgrade$1(request, handle);
webSocket.pause();
if (!(await isWebSocketOpen(webSocket))) {
await getFirstWebSocketEvent(webSocket);
}
return webSocket;
};
const signal$4 = webSocket => {
webSocket.resume();
};
const wrap$9 = webSocket => {
return {
webSocket,
/**
* @type {any}
*/
wrappedListener: undefined,
// @ts-ignore
on(event, listener) {
switch (event) {
case 'message':
// @ts-ignore
const wrappedListener = message => {
const data = deserialize(message);
const event = {
data,
target: this
};
listener(event);
};
webSocket.on('message', wrappedListener);
break;
case 'close':
webSocket.on('close', listener);
break;
default:
throw new Error('unknown event listener type');
}
},
// @ts-ignore
off(event, listener) {
this.webSocket.off(event, listener);
},
// @ts-ignore
send(message) {
const stringifiedMessage = serialize(message);
this.webSocket.send(stringifiedMessage);
},
dispose() {
this.webSocket.close();
},
start() {
throw new Error('start method is deprecated');
}
};
};
const IpcChildWithWebSocket = {
__proto__: null,
listen: listen$1$1,
signal: signal$4,
wrap: wrap$9
};
const Two = '2.0';
const create$4 = (method, params) => {
return {
jsonrpc: Two,
method,
params
};
};
const callbacks = Object.create(null);
const set$1 = (id, fn) => {
callbacks[id] = fn;
};
const get$1 = id => {
return callbacks[id];
};
const remove$1 = id => {
delete callbacks[id];
};
let id = 0;
const create$3 = () => {
return ++id;
};
const registerPromise = () => {
const id = create$3();
const {
resolve,
promise
} = Promise.withResolvers();
set$1(id, resolve);
return {
id,
promise
};
};
const create$2 = (method, params) => {
const {
id,
promise
} = registerPromise();
const message = {
jsonrpc: Two,
method,
params,
id
};
return {
message,
promise
};
};
class JsonRpcError extends Error {
constructor(message) {
super(message);
this.name = 'JsonRpcError';
}
}
const NewLine$2 = '\n';
const DomException = 'DOMException';
const ReferenceError$1 = 'ReferenceError';
const SyntaxError$1 = 'SyntaxError';
const TypeError$1 = 'TypeError';
const getErrorConstructor = (message, type) => {
if (type) {
switch (type) {
case DomException:
return DOMException;
case TypeError$1:
return TypeError;
case SyntaxError$1:
return SyntaxError;
case ReferenceError$1:
return ReferenceError;
default:
return Error;
}
}
if (message.startsWith('TypeError: ')) {
return TypeError;
}
if (message.startsWith('SyntaxError: ')) {
return SyntaxError;
}
if (message.startsWith('ReferenceError: ')) {
return ReferenceError;
}
return Error;
};
const constructError = (message, type, name) => {
const ErrorConstructor = getErrorConstructor(message, type);
if (ErrorConstructor === DOMException && name) {
return new ErrorConstructor(message, name);
}
if (ErrorConstructor === Error) {
const error = new Error(message);
if (name && name !== 'VError') {
error.name = name;
}
return error;
}
return new ErrorConstructor(message);
};
const joinLines$1 = lines => {
return lines.join(NewLine$2);
};
const splitLines$1 = lines => {
return lines.split(NewLine$2);
};
const getCurrentStack = () => {
const stackLinesToSkip = 3;
const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(stackLinesToSkip));
return currentStack;
};
const getNewLineIndex$1 = (string, startIndex = undefined) => {
return string.indexOf(NewLine$2, startIndex);
};
const getParentStack = error => {
let parentStack = error.stack || error.data || error.message || '';
if (parentStack.startsWith(' at')) {
parentStack = error.message + NewLine$2 + parentStack;
}
return parentStack;
};
const MethodNotFound = -32601;
const Custom = -32001;
const restoreJsonRpcError = error => {
const currentStack = getCurrentStack();
if (error && error instanceof Error) {
if (typeof error.stack === 'string') {
error.stack = error.stack + NewLine$2 + currentStack;
}
return error;
}
if (error && error.code && error.code === MethodNotFound) {
const restoredError = new JsonRpcError(error.message);
const parentStack = getParentStack(error);
restoredError.stack = parentStack + NewLine$2 + currentStack;
return restoredError;
}
if (error && error.message) {
const restoredError = constructError(error.message, error.type, error.name);
if (error.data) {
if (error.data.stack && error.data.type && error.message) {
restoredError.stack = error.data.type + ': ' + error.message + NewLine$2 + error.data.stack + NewLine$2 + currentStack;
} else if (error.data.stack) {
restoredError.stack = error.data.stack;
}
if (error.data.codeFrame) {
// @ts-ignore
restoredError.codeFrame = error.data.codeFrame;
}
if (error.data.code) {
// @ts-ignore
restoredError.code = error.data.code;
}
if (error.data.type) {
// @ts-ignore
restoredError.name = error.data.type;
}
} else {
if (error.stack) {
const lowerStack = restoredError.stack || '';
// @ts-ignore
const indexNewLine = getNewLineIndex$1(lowerStack);
const parentStack = getParentStack(error);
// @ts-ignore
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
}
if (error.codeFrame) {
// @ts-ignore
restoredError.codeFrame = error.codeFrame;
}
}
return restoredError;
}
if (typeof error === 'string') {
return new Error(`JsonRpc Error: ${error}`);
}
return new Error(`JsonRpc Error: ${error}`);
};
const unwrapJsonRpcResult = responseMessage => {
if ('error' in responseMessage) {
const restoredError = restoreJsonRpcError(responseMessage.error);
throw restoredError;
}
if ('result' in responseMessage) {
return responseMessage.result;
}
throw new JsonRpcError('unexpected response message');
};
const warn$1 = (...args) => {
console.warn(...args);
};
const resolve = (id, response) => {
const fn = get$1(id);
if (!fn) {
console.log(response);
warn$1(`callback ${id} may already be disposed`);
return;
}
fn(response);
remove$1(id);
};
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
const getErrorType = prettyError => {
if (prettyError && prettyError.type) {
return prettyError.type;
}
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
return prettyError.constructor.name;
}
return undefined;
};
const isAlreadyStack = line => {
return line.trim().startsWith('at ');
};
const getStack = prettyError => {
const stackString = prettyError.stack || '';
const newLineIndex = stackString.indexOf('\n');
if (newLineIndex !== -1 && !isAlreadyStack(stackString.slice(0, newLineIndex))) {
return stackString.slice(newLineIndex + 1);
}
return stackString;
};
const getErrorProperty = (error, prettyError) => {
if (error && error.code === E_COMMAND_NOT_FOUND) {
return {
code: MethodNotFound,
message: error.message,
data: error.stack
};
}
return {
code: Custom,
message: prettyError.message,
data: {
stack: getStack(prettyError),
codeFrame: prettyError.codeFrame,
type: getErrorType(prettyError),
code: prettyError.code,
name: prettyError.name
}
};
};
const create$1$1 = (id, error) => {
return {
jsonrpc: Two,
id,
error
};
};
const getErrorResponse = (id, error, preparePrettyError, logError) => {
const prettyError = preparePrettyError(error);
logError(error, prettyError);
const errorProperty = getErrorProperty(error, prettyError);
return create$1$1(id, errorProperty);
};
const create$5 = (message, result) => {
return {
jsonrpc: Two,
id: message.id,
result: result ?? null
};
};
const getSuccessResponse = (message, result) => {
const resultProperty = result ?? null;
return create$5(message, resultProperty);
};
const getErrorResponseSimple = (id, error) => {
return {
jsonrpc: Two,
id,
error: {
code: Custom,
// @ts-ignore
message: error.message,
data: error
}
};
};
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
try {
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
return getSuccessResponse(message, result);
} catch (error) {
if (ipc.canUseSimpleErrorResponse) {
return getErrorResponseSimple(message.id, error);
}
return getErrorResponse(message.id, error, preparePrettyError, logError);
}
};
const defaultPreparePrettyError = error => {
return error;
};
const defaultLogError = () => {
// ignore
};
const defaultRequiresSocket = () => {
return false;
};
const defaultResolve = resolve;
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
const normalizeParams = args => {
if (args.length === 1) {
const options = args[0];
return {
ipc: options.ipc,
message: options.message,
execute: options.execute,
resolve: options.resolve || defaultResolve,
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
logError: options.logError || defaultLogError,
requiresSocket: options.requiresSocket || defaultRequiresSocket
};
}
return {
ipc: args[0],
message: args[1],
execute: args[2],
resolve: args[3],
preparePrettyError: args[4],
logError: args[5],
requiresSocket: args[6]
};
};
const handleJsonRpcMessage = async (...args) => {
const options = normalizeParams(args);
const {
message,
ipc,
execute,
resolve,
preparePrettyError,
logError,
requiresSocket
} = options;
if ('id' in message) {
if ('method' in message) {
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
try {
ipc.send(response);
} catch (error) {
const errorResponse = getErrorResponse(message.id, error, preparePrettyError, logError);
ipc.send(errorResponse);
}
return;
}
resolve(message.id, message);
return;
}
if ('method' in message) {
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
return;
}
throw new JsonRpcError('unexpected message');
};
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
const {
message,
promise
} = create$2(method, params);
if (useSendAndTransfer && ipc.sendAndTransfer) {
ipc.sendAndTransfer(message);
} else {
ipc.send(message);
}
const responseMessage = await promise;
return unwrapJsonRpcResult(responseMessage);
};
const send = (transport, method, ...params) => {
const message = create$4(method, params);
transport.send(message);
};
const invoke = (ipc, method, ...params) => {
return invokeHelper(ipc, method, params, false);
};
const invokeAndTransfer = (ipc, method, ...params) => {
return invokeHelper(ipc, method, params, true);
};
const createRpc = ipc => {
const rpc = {
// @ts-ignore
ipc,
/**
* @deprecated
*/
send(method, ...params) {
send(ipc, method, ...params);
},
invoke(method, ...params) {
return invoke(ipc, method, ...params);
},
invokeAndTransfer(method, ...params) {
return invokeAndTransfer(ipc, method, ...params);
},
async dispose() {
await ipc?.dispose();
}
};
return rpc;
};
const requiresSocket$1 = () => {
return false;
};
const preparePrettyError = error => {
return error;
};
const logError = () => {
// handled by renderer worker
};
const handleMessage = event => {
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket$1;
const actualExecute = event?.target?.execute || execute;
return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
};
const handleIpc = ipc => {
if ('addEventListener' in ipc) {
ipc.addEventListener('message', handleMessage);
} else if ('on' in ipc) {
// deprecated
ipc.on('message', handleMessage);
}
};
const listen$2 = async (module, options) => {
const rawIpc = await module.listen(options);
if (module.signal) {
module.signal(rawIpc);
}
const ipc = module.wrap(rawIpc);
return ipc;
};
const create$k = async ({
commandMap,
messagePort,
requiresSocket
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$2(IpcChildWithElectronMessagePort$1, {
messagePort
});
if (requiresSocket) {
ipc.requiresSocket = requiresSocket;
}
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const ElectronMessagePortRpcClient = {
__proto__: null,
create: create$k
};
const create$j = async ({
commandMap
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$2(IpcChildWithElectronUtilityProcess$1);
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const ElectronUtilityProcessRpcClient = {
__proto__: null,
create: create$j
};
const create$a = async ({
commandMap
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$2(IpcChildWithNodeForkedProcess$1);
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const NodeForkedProcessRpcClient = {
__proto__: null,
create: create$a
};
const create$8 = async ({
commandMap,
request,
handle,
requiresSocket
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$2(IpcChildWithWebSocket, {
request,
handle
});
if (requiresSocket) {
ipc.requiresSocket = requiresSocket;
}
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const NodeWebSocketRpcClient = {
__proto__: null,
create: create$8
};
const METHODS_THAT_REQUIRE_SOCKET = new Set(['Terminal.create']);
const requiresSocket = method => {
return METHODS_THAT_REQUIRE_SOCKET.has(method);
};
const handleElectronMessagePort = async messagePort => {
object(messagePort);
await ElectronMessagePortRpcClient.create({
commandMap: {},
messagePort,
requiresSocket: requiresSocket
});
};
const NodeWorker = 1;
const NodeForkedProcess = 2;
const WebSocket = 3;
const ElectronUtilityProcess = 4;
const ElectronMessagePort = 5;
const NodeMessagePort = 6;
const Auto = () => {
const {
argv
} = process;
if (argv.includes('--ipc-type=node-worker')) {
return NodeWorker;
}
if (argv.includes('--ipc-type=node-forked-process')) {
return NodeForkedProcess;
}
if (argv.includes('--ipc-type=electron-utility-process')) {
return ElectronUtilityProcess;
}
throw new Error(`[pty-host] unknown ipc type`);
};
const getModule = method => {
switch (method) {
case NodeForkedProcess:
return NodeForkedProcessRpcClient;
case WebSocket:
return NodeWebSocketRpcClient;
case ElectronUtilityProcess:
return ElectronUtilityProcessRpcClient;
case ElectronMessagePort:
return ElectronMessagePortRpcClient;
default:
throw new Error('unexpected ipc type');
}
};
const listen$1 = async ({
method,
...params
}) => {
const module = getModule(method);
// @ts-ignore
const rpc = await module.create(params);
return rpc;
};
const handleNodeMessagePort = async messagePort => {
await listen$1({
method: NodeMessagePort,
messagePort
});
};
const handleWebSocket = async (handle, request) => {
object(handle);
object(request);
await NodeWebSocketRpcClient.create({
commandMap: {},
handle,
request,
requiresSocket: requiresSocket
});
};
const debug = debugModule('pty-host');
class DataEvent extends Event {
constructor(data) {
super('data');
this.data = data;
}
}
class ExitEvent extends Event {
constructor(data) {
super('exit');
this.data = data;
}
}
class Pty extends EventTarget {
/**
*
* @param {import('node-pty').IPty} pty
*/
constructor(pty) {
super();
this.pty = pty;
const handleData = data => {
this.dispatchEvent(new DataEvent(data));
};
const handleExit = data => {
this.dispatchEvent(new ExitEvent(data));
};
this.pty.onData(handleData);
this.pty.onExit(handleExit);
}
resize(columns, rows) {
this.pty.resize(columns, rows);
}
dispose() {
this.pty.kill();
}
write(data) {
this.pty.write(data);
}
}
/**
*
* @param {*} param0
* @returns {any}
*/
const create$1 = ({
cwd,
command,
args
} = {}) => {
try {
string(cwd);
string(command);
array(args);
const pty = spawn(command, args, {
encoding: null,
cwd
// cols: 10,
// rows: 10,
});
const wrapped = new Pty(pty);
return wrapped;
} catch (error) {
throw new VError(error, `Failed to create terminal`);
}
};
const state$1 = {
ptyMap: Object.create(null)
};
const set = (id, pty) => {
state$1.ptyMap[id] = pty;
};
const get = id => {
return state$1.ptyMap[id];
};
const remove = id => {
delete state$1.ptyMap[id];
};
// TODO maybe merge pty and pty controller
const create = (ipc, id, cwd, command, args) => {
number(id);
string(cwd);
string(command);
array(args);
object(ipc);
debug(`create ${id} ${cwd}`);
// @ts-ignore
const pty = create$1({
cwd,
command,
args
});
const handleData = event => {
ipc.send({
jsonrpc: '2.0',
method: 'Viewlet.send',
params: [id, 'handleData', event.data]
});
};
pty.addEventListener('data', handleData);
set(id, pty);
};
const write = (id, data) => {
const pty = get(id);
if (!pty) {
throw new Error(`pty ${id} not found`);
}
pty.write(data);
};
const resize = (id, columns, rows) => {
const pty = get(id);
if (!pty) {
throw new Error(`pty ${id} not found`);
}
pty.resize(columns, rows);
};
const dispose = id => {
const pty = get(id);
if (!pty) {
throw new Error(`pty ${id} not found`);
}
pty.dispose();
remove(id);
};
const HandleElectronMessagePort = 'HandleElectronMessagePort.handleElectronMessagePort';
const HandleNodeMessagePort = 'HandleNodeMessagePort.handleNodeMessagePort';
const HandleWebSocket = 'HandleWebSocket.handleWebSocket';
const TerminalCreate = 'Terminal.create';
const TerminalResize = 'Terminal.resize';
const TerminalWrite = 'Terminal.write';
const TerminalDispose = 'Terminal.dispose';
const commandMap = {
[HandleElectronMessagePort]: handleElectronMessagePort,
[HandleNodeMessagePort]: handleNodeMessagePort,
[HandleWebSocket]: handleWebSocket,
[TerminalCreate]: create,
[TerminalResize]: resize,
[TerminalWrite]: write,
[TerminalDispose]: dispose
};
const listen = async () => {
await listen$1({
method: Auto()
});
};
const NewLine$1 = '\n';
const Error$1 = 1;
const Success = 0;
/**
*
* @param {string} string
* @param {number|undefined} startIndex
* @returns
*/
const getNewLineIndex = (string, startIndex = undefined) => {
return string.indexOf(NewLine$1, startIndex);
};
const EPIPE = 'EPIPE';
const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED';
const exit = code => {
process.exit(code);
};
const setExitCode = exitCode => {
process.exitCode = exitCode;
};
const isConnected = () => {
return process.connected;
};
const isIgnoredError = error => {
if (error && error.code === EPIPE && !process.connected) {
// parent process is disposed, ignore
return true;
}
if (error && error.code === ERR_IPC_CHANNEL_CLOSED && !isConnected()) {
// parent process is disposed, ignore
return true;
}
return false;
};
// TODO mock this module when used in unit tests
const state = {
console: undefined
};
const createConsole = () => {
const logFile = `${tmpdir()}/log-terminal-process.txt`;
const writeStream = createWriteStream(logFile);
const logger = new Console(writeStream);
return logger;
};
const getOrCreateLogger = () => {
if (!state.console) {
state.console = createConsole();
}
return state.console;
};
const info = (...args) => {
const logger = getOrCreateLogger();
logger.info(...args);
console.info(...args);
};
const error = (...args) => {
const logger = getOrCreateLogger();
logger.error(...args);
console.error(...args);
};
var lib$1 = {};
var picocolors = {exports: {}};
var hasRequiredPicocolors;
function requirePicocolors () {
if (hasRequiredPicocolors) return picocolors.exports;
hasRequiredPicocolors = 1;
let p = process || {},
argv = p.argv || [],
env = p.env || {};
let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
let formatter = (open, close, replace = open) => input => {
let string = "" + input,
index = string.indexOf(close, open.length);
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
};
let replaceClose = (string, close, replace, index) => {
let result = "",
cursor = 0;
do {
result += string.substring(cursor, index) + replace;
cursor = index + close.length;
index = string.indexOf(close, cursor);
} while (~index);
return result + string.substring(cursor);
};
let createColors = (enabled = isColorSupported) => {
let f = enabled ? formatter : () => String;
return {
isColorSupported: enabled,
reset: f("\x1b[0m", "\x1b[0m"),
bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
italic: f("\x1b[3m", "\x1b[23m"),
underline: f("\x1b[4m", "\x1b[24m"),
inverse: f("\x1b[7m", "\x1b[27m"),
hidden: f("\x1b[8m", "\x1b[28m"),
strikethrough: f("\x1b[9m", "\x1b[29m"),
black: f("\x1b[30m", "\x1b[39m"),
red: f("\x1b[31m", "\x1b[39m"),
green: f("\x1b[32m", "\x1b[39m"),
yellow: f("\x1b[33m", "\x1b[39m"),
blue: f("\x1b[34m", "\x1b[39m"),
magenta: f("\x1b[35m", "\x1b[39m"),
cyan: f("\x1b[36m", "\x1b[39m"),
white: f("\x1b[37m", "\x1b[39m"),
gray: f("\x1b[90m", "\x1b[39m"),
bgBlack: f("\x1b[40m", "\x1b[49m"),
bgRed: f("\x1b[41m", "\x1b[49m"),
bgGreen: f("\x1b[42m", "\x1b[49m"),
bgYellow: f("\x1b[43m", "\x1b[49m"),
bgBlue: f("\x1b[44m", "\x1b[49m"),
bgMagenta: f("\x1b[45m", "\x1b[49m"),
bgCyan: f("\x1b[46m", "\x1b[49m"),
bgWhite: f("\x1b[47m", "\x1b[49m"),
blackBright: f("\x1b[90m", "\x1b[39m"),
redBright: f("\x1b[91m", "\x1b[39m"),
greenBright: f("\x1b[92m", "\x1b[39m"),
yellowBright: f("\x1b[93m", "\x1b[39m"),
blueBright: f("\x1b[94m", "\x1b[39m"),
magentaBright: f("\x1b[95m", "\x1b[39m"),
cyanBright: f("\x1b[96m", "\x1b[39m"),
whiteBright: f("\x1b[97m", "\x1b[39m"),
bgBlackBright: f("\x1b[100m", "\x1b[49m"),
bgRedBright: f("\x1b[101m", "\x1b[49m"),
bgGreenBright: f("\x1b[102m", "\x1b[49m"),
bgYellowBright: f("\x1b[103m", "\x1b[49m"),
bgBlueBright: f("\x1b[104m", "\x1b[49m"),
bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
bgCyanBright: f("\x1b[106m", "\x1b[49m"),
bgWhiteBright: f("\x1b[107m", "\x1b[49m")
};
};
picocolors.exports = createColors();
picocolors.exports.createColors = createColors;
return picocolors.exports;
}
var jsTokens = {};
var hasRequiredJsTokens;
function requireJsTokens () {
if (hasRequiredJsTokens) return jsTokens;
hasRequiredJsTokens = 1;
// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell
// License: MIT. (See LICENSE.)
Object.defineProperty(jsTokens, "__esModule", {
value: true
});
// This regex comes from regex.coffee, and is inserted here by generate-index.js
// (run `npm run build`).
jsTokens.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g;
jsTokens.matchToToken = function (match) {
var token = {
type: "invalid",
value: match[0],
closed: undefined
};
if (match[1]) token.type = "string", token.closed = !!(match[3] || match[4]);else if (match[5]) token.type = "comment";else if (match[6]) token.type = "comment", token.closed = !!match[7];else if (match[8]) token.type = "regex";else if (match[9]) token.type = "number";else if (match[10]) token.type = "name";else if (match[11]) token.type = "punctuator";else if (match[12]) token.type = "whitespace";
return token;
};
return jsTokens;
}
var lib = {};
var identifier = {};
var hasRequiredIdentifier;
function requireIdentifier () {
if (hasRequiredIdentifier) return identifier;
hasRequiredIdentifier = 1;
Object.defineProperty(identifier, "__esModule", {
value: true
});
identifier.isIdentifierChar = isIdentifierChar;
identifier.isIdentifierName = isIdentifierName;
identifier.isIdentifierStart = isIdentifierStart;
let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
let nonASCIIidentifierChars = "\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48