@lvce-editor/pty-host
Version:
Terminal process used in Lvce Editor.
1,765 lines (1,695 loc) • 75.8 kB
JavaScript
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { Console } from 'node:console';
import { createWriteStream, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { Buffer as Buffer$1 } 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);
};
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$1 = 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$1;
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 serializeError = error => {
if (error && typeof error === 'object') {
return {
errorCode: 'code' in error && typeof error.code === 'string' ? error.code : undefined,
errorMessage: 'message' in error && typeof error.message === 'string' ? error.message : 'Unknown error',
errorStack: 'stack' in error && typeof error.stack === 'string' ? error.stack : undefined
};
}
if (typeof error === 'string') {
return {
errorCode: undefined,
errorMessage: error,
errorStack: undefined
};
}
return {
errorCode: undefined,
errorMessage: 'Unknown error',
errorStack: undefined
};
};
const toPath$1 = pathOrUri => {
if (pathOrUri.startsWith('file://')) {
return fileURLToPath(pathOrUri);
}
return pathOrUri;
};
const toString = chunks => {
return Buffer.concat(chunks).toString();
};
const executeShellCommand = async ({
args,
cwd,
toSpawn
}) => {
array(args);
string(cwd);
string(toSpawn);
try {
const {
promise,
resolve
} = Promise.withResolvers();
const childProcess = spawn(toSpawn, args, {
cwd: toPath$1(cwd)
});
const stdoutChunks = [];
const stderrChunks = [];
const handleStdoutData = chunk => {
stdoutChunks.push(chunk);
};
const handleStderrData = chunk => {
stderrChunks.push(chunk);
};
const cleanup = () => {
childProcess.stdout.off('data', handleStdoutData);
childProcess.stderr.off('data', handleStderrData);
childProcess.off('error', handleError);
childProcess.off('close', handleClose);
};
const resolveWithCleanup = result => {
cleanup();
resolve(result);
};
const handleError = error => {
resolveWithCleanup(serializeError(error));
};
const handleClose = exitCode => {
resolveWithCleanup({
exitCode,
stderr: toString(stderrChunks),
stdout: toString(stdoutChunks)
});
};
childProcess.stdout.on('data', handleStdoutData);
childProcess.stderr.on('data', handleStderrData);
childProcess.on('error', handleError);
childProcess.on('close', handleClose);
return await promise;
} catch (error) {
return serializeError(error);
}
};
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;
}
}
}
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 {
code: ERR_MODULE_NOT_FOUND$1,
message
};
};
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 {
code: E_INCOMPATIBLE_NATIVE_MODULE,
message: `Incompatible native node module: ${message}`
};
};
const getModuleSyntaxError = () => {
return {
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
message: `ES Modules are 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 {
code: '',
message: actualMessage,
stack: rest
};
};
class IpcError extends VError {
// @ts-ignore
constructor(betterMessage, stdout = '', stderr = '') {
if (stdout || stderr) {
// @ts-ignore
const {
code,
message,
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 IpcError('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 IpcError('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 {
promise,
resolve
} = 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({
event,
type
});
};
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.CLOSED:
return {
event: undefined,
type: Close
};
case WebSocket.OPEN:
return {
event: undefined,
type: Open
};
}
// @ts-ignore
const {
event,
type
} = await getFirstEvent(webSocket, {
close: Close,
open: Open
});
return {
event,
type
};
};
// @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 ({
handle,
request
}) => {
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 {
dispose() {
this.webSocket.close();
},
// @ts-ignore
off(event, listener) {
this.webSocket.off(event, listener);
},
// @ts-ignore
on(event, listener) {
switch (event) {
case 'close':
webSocket.on('close', listener);
break;
case 'message':
// @ts-ignore
const wrappedListener = message => {
const data = deserialize(message);
const event = {
data,
target: this
};
listener(event);
};
webSocket.on('message', wrappedListener);
break;
default:
throw new Error('unknown event listener type');
}
},
// @ts-ignore
send(message) {
const stringifiedMessage = serialize(message);
this.webSocket.send(stringifiedMessage);
},
start() {
throw new Error('start method is deprecated');
},
webSocket,
/**
* @type {any}
*/
wrappedListener: undefined
};
};
const IpcChildWithWebSocket = {
__proto__: null,
listen: listen$1$1,
signal: signal$4,
wrap: wrap$9
};
const Two$1 = '2.0';
const callbacks = Object.create(null);
const get$1 = id => {
return callbacks[id];
};
const remove$1 = id => {
delete callbacks[id];
};
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 ReferenceError$1:
return ReferenceError;
case SyntaxError$1:
return SyntaxError;
case TypeError$1:
return TypeError;
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,
data: error.stack,
message: error.message
};
}
return {
code: Custom,
data: {
code: prettyError.code,
codeFrame: prettyError.codeFrame,
name: prettyError.name,
stack: getStack(prettyError),
type: getErrorType(prettyError)
},
message: prettyError.message
};
};
const create$1$1 = (id, error) => {
return {
error,
id,
jsonrpc: Two$1
};
};
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$9 = (message, result) => {
return {
id: message.id,
jsonrpc: Two$1,
result: result ?? null
};
};
const getSuccessResponse = (message, result) => {
const resultProperty = result ?? null;
return create$9(message, resultProperty);
};
const getErrorResponseSimple = (id, error) => {
return {
error: {
code: Custom,
data: error,
// @ts-ignore
message: error.message
},
id,
jsonrpc: Two$1
};
};
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 {
execute: options.execute,
ipc: options.ipc,
logError: options.logError || defaultLogError,
message: options.message,
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
requiresSocket: options.requiresSocket || defaultRequiresSocket,
resolve: options.resolve || defaultResolve
};
}
return {
execute: args[2],
ipc: args[0],
logError: args[5],
message: args[1],
preparePrettyError: args[4],
requiresSocket: args[6],
resolve: args[3]
};
};
const handleJsonRpcMessage = async (...args) => {
const options = normalizeParams(args);
const {
execute,
ipc,
logError,
message,
preparePrettyError,
requiresSocket,
resolve
} = 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 Two = '2.0';
const create$8 = (method, params) => {
return {
jsonrpc: Two,
method,
params
};
};
const create$7 = (id, method, params) => {
const message = {
id,
jsonrpc: Two,
method,
params
};
return message;
};
let id = 0;
const create$6 = () => {
return ++id;
};
const registerPromise = map => {
const id = create$6();
const {
promise,
resolve
} = Promise.withResolvers();
map[id] = resolve;
return {
id,
promise
};
};
const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer) => {
const {
id,
promise
} = registerPromise(callbacks);
const message = create$7(id, method, params);
if (useSendAndTransfer && ipc.sendAndTransfer) {
ipc.sendAndTransfer(message);
} else {
ipc.send(message);
}
const responseMessage = await promise;
return unwrapJsonRpcResult(responseMessage);
};
const createRpc = ipc => {
const callbacks = Object.create(null);
ipc._resolve = (id, response) => {
const fn = callbacks[id];
if (!fn) {
console.warn(`callback ${id} may already be disposed`);
return;
}
fn(response);
delete callbacks[id];
};
const rpc = {
async dispose() {
await ipc?.dispose();
},
invoke(method, ...params) {
return invokeHelper(callbacks, ipc, method, params, false);
},
invokeAndTransfer(method, ...params) {
return invokeHelper(callbacks, ipc, method, params, true);
},
// @ts-ignore
ipc,
/**
* @deprecated
*/
send(method, ...params) {
const message = create$8(method, params);
ipc.send(message);
}
};
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, event.target._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$5 = 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$5
};
const create$4 = 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$4
};
const create$3 = 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$3
};
const create$2 = async ({
commandMap,
handle,
request,
requiresSocket
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$2(IpcChildWithWebSocket, {
handle,
request
});
if (requiresSocket) {
ipc.requiresSocket = requiresSocket;
}
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const NodeWebSocketRpcClient = {
__proto__: null,
create: create$2
};
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 create$5({
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=websocket')) {
return WebSocket;
}
if (argv.includes('--ipc-type=electron-utility-process')) {
return ElectronUtilityProcess;
}
throw new Error(`[pty-host] unknown ipc type`);
};
const getModule = method => {
switch (method) {
case ElectronMessagePort:
return ElectronMessagePortRpcClient;
case ElectronUtilityProcess:
return ElectronUtilityProcessRpcClient;
case NodeForkedProcess:
return NodeForkedProcessRpcClient;
case WebSocket:
return NodeWebSocketRpcClient;
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({
messagePort,
method: NodeMessagePort
});
};
const handleWebSocket = async (handle, request) => {
object(handle);
object(request);
await create$2({
commandMap: {},
handle,
request,
requiresSocket: requiresSocket
});
};
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);
}
}
const toPath = pathOrUri => {
if (pathOrUri && pathOrUri.startsWith('file://')) {
return fileURLToPath(pathOrUri);
}
return pathOrUri;
};
/**
*
* @param {*} param0
* @returns {Promise<any>}
*/
const create$1 = async ({
args,
command,
cwd
} = {}) => {
try {
string(cwd);
string(command);
array(args);
const {
spawn
} = await import('node-pty');
const cwdPath = toPath(cwd);
const pty = spawn(command, args, {
cwd: cwdPath,
encoding: null
// 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 = async (ipc, id, cwd, command, args) => {
number(id);
string(cwd);
string(command);
array(args);
object(ipc);
// @ts-ignore
const pty = await create$1({
args,
command,
cwd
});
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 TerminalExecuteShellCommand = 'Terminal.executeShellCommand';
const TerminalResize = 'Terminal.resize';
const TerminalWrite = 'Terminal.write';
const TerminalDispose = 'Terminal.dispose';
const commandMap = {
[HandleElectronMessagePort]: handleElectronMessagePort,
[HandleNodeMessagePort]: handleNodeMessagePort,
[HandleWebSocket]: handleWebSocket,
[TerminalCreate]: create,
[TerminalDispose]: dispose,
[TerminalExecuteShellCommand]: executeShellCommand,
[TerminalResize]: resize,
[TerminalWrite]: write
};
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 => {
return Boolean(error && (error.code === EPIPE && !process.connected || error.code === ERR_IPC_CHANNEL_CLOSED && !isConnected()));
};
// 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-\u088f\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\u0c5c\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdc-\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-\ua7dc\ua7f1-\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