first commit
This commit is contained in:
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/CreateFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/CreateFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class CreateFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/CreateFileError.js
generated
vendored
Normal file
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/CreateFileError.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CreateFileError = void 0;
|
||||
class CreateFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to create temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
exports.CreateFileError = CreateFileError;
|
||||
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/LaunchEditorError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/LaunchEditorError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class LaunchEditorError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/LaunchEditorError.js
generated
vendored
Normal file
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/LaunchEditorError.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LaunchEditorError = void 0;
|
||||
class LaunchEditorError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to launch editor. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
exports.LaunchEditorError = LaunchEditorError;
|
||||
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/ReadFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/ReadFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class ReadFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/ReadFileError.js
generated
vendored
Normal file
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/ReadFileError.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ReadFileError = void 0;
|
||||
class ReadFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to read temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
exports.ReadFileError = ReadFileError;
|
||||
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/RemoveFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/commonjs/errors/RemoveFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class RemoveFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/RemoveFileError.js
generated
vendored
Normal file
17
node_modules/@inquirer/external-editor/dist/commonjs/errors/RemoveFileError.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RemoveFileError = void 0;
|
||||
class RemoveFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to remove temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
exports.RemoveFileError = RemoveFileError;
|
||||
39
node_modules/@inquirer/external-editor/dist/commonjs/index.d.ts
generated
vendored
Normal file
39
node_modules/@inquirer/external-editor/dist/commonjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { CreateFileError } from './errors/CreateFileError.js';
|
||||
import { LaunchEditorError } from './errors/LaunchEditorError.js';
|
||||
import { ReadFileError } from './errors/ReadFileError.js';
|
||||
import { RemoveFileError } from './errors/RemoveFileError.js';
|
||||
export interface IEditorParams {
|
||||
args: string[];
|
||||
bin: string;
|
||||
}
|
||||
export interface IFileOptions {
|
||||
prefix?: string;
|
||||
postfix?: string;
|
||||
mode?: number;
|
||||
template?: string;
|
||||
dir?: string;
|
||||
}
|
||||
export type StringCallback = (err: Error | undefined, result: string | undefined) => void;
|
||||
export type VoidCallback = () => void;
|
||||
export { CreateFileError, LaunchEditorError, ReadFileError, RemoveFileError };
|
||||
export declare function edit(text?: string, fileOptions?: IFileOptions): string;
|
||||
export declare function editAsync(text: string | undefined, callback: StringCallback, fileOptions?: IFileOptions): void;
|
||||
export declare class ExternalEditor {
|
||||
text: string;
|
||||
tempFile: string;
|
||||
editor: IEditorParams;
|
||||
lastExitStatus: number;
|
||||
private fileOptions;
|
||||
get temp_file(): string;
|
||||
get last_exit_status(): number;
|
||||
constructor(text?: string, fileOptions?: IFileOptions);
|
||||
run(): string;
|
||||
runAsync(callback: StringCallback): void;
|
||||
cleanup(): void;
|
||||
private determineEditor;
|
||||
private createTemporaryFile;
|
||||
private readTemporaryFile;
|
||||
private removeTemporaryFile;
|
||||
private launchEditor;
|
||||
private launchEditorAsync;
|
||||
}
|
||||
203
node_modules/@inquirer/external-editor/dist/commonjs/index.js
generated
vendored
Normal file
203
node_modules/@inquirer/external-editor/dist/commonjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExternalEditor = exports.RemoveFileError = exports.ReadFileError = exports.LaunchEditorError = exports.CreateFileError = void 0;
|
||||
exports.edit = edit;
|
||||
exports.editAsync = editAsync;
|
||||
const chardet_1 = require("chardet");
|
||||
const child_process_1 = require("child_process");
|
||||
const fs_1 = require("fs");
|
||||
const node_path_1 = __importDefault(require("node:path"));
|
||||
const node_os_1 = __importDefault(require("node:os"));
|
||||
const node_crypto_1 = require("node:crypto");
|
||||
const iconv_lite_1 = __importDefault(require("iconv-lite"));
|
||||
const CreateFileError_js_1 = require("./errors/CreateFileError.js");
|
||||
Object.defineProperty(exports, "CreateFileError", { enumerable: true, get: function () { return CreateFileError_js_1.CreateFileError; } });
|
||||
const LaunchEditorError_js_1 = require("./errors/LaunchEditorError.js");
|
||||
Object.defineProperty(exports, "LaunchEditorError", { enumerable: true, get: function () { return LaunchEditorError_js_1.LaunchEditorError; } });
|
||||
const ReadFileError_js_1 = require("./errors/ReadFileError.js");
|
||||
Object.defineProperty(exports, "ReadFileError", { enumerable: true, get: function () { return ReadFileError_js_1.ReadFileError; } });
|
||||
const RemoveFileError_js_1 = require("./errors/RemoveFileError.js");
|
||||
Object.defineProperty(exports, "RemoveFileError", { enumerable: true, get: function () { return RemoveFileError_js_1.RemoveFileError; } });
|
||||
function edit(text = '', fileOptions) {
|
||||
const editor = new ExternalEditor(text, fileOptions);
|
||||
editor.run();
|
||||
editor.cleanup();
|
||||
return editor.text;
|
||||
}
|
||||
function editAsync(text = '', callback, fileOptions) {
|
||||
const editor = new ExternalEditor(text, fileOptions);
|
||||
editor.runAsync((err, result) => {
|
||||
if (err) {
|
||||
setImmediate(callback, err, undefined);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
editor.cleanup();
|
||||
setImmediate(callback, undefined, result);
|
||||
}
|
||||
catch (cleanupError) {
|
||||
setImmediate(callback, cleanupError, undefined);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function sanitizeAffix(affix) {
|
||||
if (!affix)
|
||||
return '';
|
||||
return affix.replace(/[^a-zA-Z0-9_.-]/g, '_');
|
||||
}
|
||||
function splitStringBySpace(str) {
|
||||
const pieces = [];
|
||||
let currentString = '';
|
||||
for (let strIndex = 0; strIndex < str.length; strIndex++) {
|
||||
const currentLetter = str.charAt(strIndex);
|
||||
if (strIndex > 0 &&
|
||||
currentLetter === ' ' &&
|
||||
str[strIndex - 1] !== '\\' &&
|
||||
currentString.length > 0) {
|
||||
pieces.push(currentString);
|
||||
currentString = '';
|
||||
}
|
||||
else {
|
||||
currentString = `${currentString}${currentLetter}`;
|
||||
}
|
||||
}
|
||||
if (currentString.length > 0) {
|
||||
pieces.push(currentString);
|
||||
}
|
||||
return pieces;
|
||||
}
|
||||
class ExternalEditor {
|
||||
text = '';
|
||||
tempFile;
|
||||
editor;
|
||||
lastExitStatus = 0;
|
||||
fileOptions = {};
|
||||
get temp_file() {
|
||||
console.log('DEPRECATED: temp_file. Use tempFile moving forward.');
|
||||
return this.tempFile;
|
||||
}
|
||||
get last_exit_status() {
|
||||
console.log('DEPRECATED: last_exit_status. Use lastExitStatus moving forward.');
|
||||
return this.lastExitStatus;
|
||||
}
|
||||
constructor(text = '', fileOptions) {
|
||||
this.text = text;
|
||||
if (fileOptions) {
|
||||
this.fileOptions = fileOptions;
|
||||
}
|
||||
this.determineEditor();
|
||||
this.createTemporaryFile();
|
||||
}
|
||||
run() {
|
||||
this.launchEditor();
|
||||
this.readTemporaryFile();
|
||||
return this.text;
|
||||
}
|
||||
runAsync(callback) {
|
||||
try {
|
||||
this.launchEditorAsync(() => {
|
||||
try {
|
||||
this.readTemporaryFile();
|
||||
setImmediate(callback, undefined, this.text);
|
||||
}
|
||||
catch (readError) {
|
||||
setImmediate(callback, readError, undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (launchError) {
|
||||
setImmediate(callback, launchError, undefined);
|
||||
}
|
||||
}
|
||||
cleanup() {
|
||||
this.removeTemporaryFile();
|
||||
}
|
||||
determineEditor() {
|
||||
const editor = process.env['VISUAL']
|
||||
? process.env['VISUAL']
|
||||
: process.env['EDITOR']
|
||||
? process.env['EDITOR']
|
||||
: process.platform.startsWith('win')
|
||||
? 'notepad'
|
||||
: 'vim';
|
||||
const editorOpts = splitStringBySpace(editor).map((piece) => piece.replace('\\ ', ' '));
|
||||
const bin = editorOpts.shift();
|
||||
this.editor = { args: editorOpts, bin };
|
||||
}
|
||||
createTemporaryFile() {
|
||||
try {
|
||||
const baseDir = this.fileOptions.dir ?? node_os_1.default.tmpdir();
|
||||
const id = (0, node_crypto_1.randomUUID)();
|
||||
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
||||
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
||||
const filename = `${prefix}${id}${postfix}`;
|
||||
const candidate = node_path_1.default.resolve(baseDir, filename);
|
||||
const baseResolved = node_path_1.default.resolve(baseDir) + node_path_1.default.sep;
|
||||
if (!candidate.startsWith(baseResolved)) {
|
||||
throw new Error('Resolved temporary file escaped the base directory');
|
||||
}
|
||||
this.tempFile = candidate;
|
||||
const opt = { encoding: 'utf8', flag: 'wx' };
|
||||
if (Object.prototype.hasOwnProperty.call(this.fileOptions, 'mode')) {
|
||||
opt.mode = this.fileOptions.mode;
|
||||
}
|
||||
(0, fs_1.writeFileSync)(this.tempFile, this.text, opt);
|
||||
}
|
||||
catch (createFileError) {
|
||||
throw new CreateFileError_js_1.CreateFileError(createFileError);
|
||||
}
|
||||
}
|
||||
readTemporaryFile() {
|
||||
try {
|
||||
const tempFileBuffer = (0, fs_1.readFileSync)(this.tempFile);
|
||||
if (tempFileBuffer.length === 0) {
|
||||
this.text = '';
|
||||
}
|
||||
else {
|
||||
let encoding = (0, chardet_1.detect)(tempFileBuffer) ?? 'utf8';
|
||||
if (!iconv_lite_1.default.encodingExists(encoding)) {
|
||||
// Probably a bad idea, but will at least prevent crashing
|
||||
encoding = 'utf8';
|
||||
}
|
||||
this.text = iconv_lite_1.default.decode(tempFileBuffer, encoding);
|
||||
}
|
||||
}
|
||||
catch (readFileError) {
|
||||
throw new ReadFileError_js_1.ReadFileError(readFileError);
|
||||
}
|
||||
}
|
||||
removeTemporaryFile() {
|
||||
try {
|
||||
(0, fs_1.unlinkSync)(this.tempFile);
|
||||
}
|
||||
catch (removeFileError) {
|
||||
throw new RemoveFileError_js_1.RemoveFileError(removeFileError);
|
||||
}
|
||||
}
|
||||
launchEditor() {
|
||||
try {
|
||||
const editorProcess = (0, child_process_1.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: 'inherit' });
|
||||
this.lastExitStatus = editorProcess.status ?? 0;
|
||||
}
|
||||
catch (launchError) {
|
||||
throw new LaunchEditorError_js_1.LaunchEditorError(launchError);
|
||||
}
|
||||
}
|
||||
launchEditorAsync(callback) {
|
||||
try {
|
||||
const editorProcess = (0, child_process_1.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: 'inherit' });
|
||||
editorProcess.on('exit', (code) => {
|
||||
this.lastExitStatus = code;
|
||||
setImmediate(callback);
|
||||
});
|
||||
}
|
||||
catch (launchError) {
|
||||
throw new LaunchEditorError_js_1.LaunchEditorError(launchError);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ExternalEditor = ExternalEditor;
|
||||
3
node_modules/@inquirer/external-editor/dist/commonjs/package.json
generated
vendored
Normal file
3
node_modules/@inquirer/external-editor/dist/commonjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
10
node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class CreateFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
13
node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js
generated
vendored
Normal file
13
node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export class CreateFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to create temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
10
node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class LaunchEditorError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
13
node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js
generated
vendored
Normal file
13
node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export class LaunchEditorError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to launch editor. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
10
node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class ReadFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
13
node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js
generated
vendored
Normal file
13
node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export class ReadFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to read temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
10
node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export declare class RemoveFileError extends Error {
|
||||
originalError: Error;
|
||||
constructor(originalError: Error);
|
||||
}
|
||||
13
node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js
generated
vendored
Normal file
13
node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/***
|
||||
* Node External Editor
|
||||
*
|
||||
* Kevin Gravier <kevin@mrkmg.com>
|
||||
* MIT 2018
|
||||
*/
|
||||
export class RemoveFileError extends Error {
|
||||
originalError;
|
||||
constructor(originalError) {
|
||||
super(`Failed to remove temporary file. ${originalError.message}`);
|
||||
this.originalError = originalError;
|
||||
}
|
||||
}
|
||||
39
node_modules/@inquirer/external-editor/dist/esm/index.d.ts
generated
vendored
Normal file
39
node_modules/@inquirer/external-editor/dist/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { CreateFileError } from './errors/CreateFileError.js';
|
||||
import { LaunchEditorError } from './errors/LaunchEditorError.js';
|
||||
import { ReadFileError } from './errors/ReadFileError.js';
|
||||
import { RemoveFileError } from './errors/RemoveFileError.js';
|
||||
export interface IEditorParams {
|
||||
args: string[];
|
||||
bin: string;
|
||||
}
|
||||
export interface IFileOptions {
|
||||
prefix?: string;
|
||||
postfix?: string;
|
||||
mode?: number;
|
||||
template?: string;
|
||||
dir?: string;
|
||||
}
|
||||
export type StringCallback = (err: Error | undefined, result: string | undefined) => void;
|
||||
export type VoidCallback = () => void;
|
||||
export { CreateFileError, LaunchEditorError, ReadFileError, RemoveFileError };
|
||||
export declare function edit(text?: string, fileOptions?: IFileOptions): string;
|
||||
export declare function editAsync(text: string | undefined, callback: StringCallback, fileOptions?: IFileOptions): void;
|
||||
export declare class ExternalEditor {
|
||||
text: string;
|
||||
tempFile: string;
|
||||
editor: IEditorParams;
|
||||
lastExitStatus: number;
|
||||
private fileOptions;
|
||||
get temp_file(): string;
|
||||
get last_exit_status(): number;
|
||||
constructor(text?: string, fileOptions?: IFileOptions);
|
||||
run(): string;
|
||||
runAsync(callback: StringCallback): void;
|
||||
cleanup(): void;
|
||||
private determineEditor;
|
||||
private createTemporaryFile;
|
||||
private readTemporaryFile;
|
||||
private removeTemporaryFile;
|
||||
private launchEditor;
|
||||
private launchEditorAsync;
|
||||
}
|
||||
191
node_modules/@inquirer/external-editor/dist/esm/index.js
generated
vendored
Normal file
191
node_modules/@inquirer/external-editor/dist/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
import { detect } from 'chardet';
|
||||
import { spawn, spawnSync } from 'child_process';
|
||||
import { readFileSync, unlinkSync, writeFileSync } from 'fs';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import iconv from 'iconv-lite';
|
||||
import { CreateFileError } from './errors/CreateFileError.js';
|
||||
import { LaunchEditorError } from './errors/LaunchEditorError.js';
|
||||
import { ReadFileError } from './errors/ReadFileError.js';
|
||||
import { RemoveFileError } from './errors/RemoveFileError.js';
|
||||
export { CreateFileError, LaunchEditorError, ReadFileError, RemoveFileError };
|
||||
export function edit(text = '', fileOptions) {
|
||||
const editor = new ExternalEditor(text, fileOptions);
|
||||
editor.run();
|
||||
editor.cleanup();
|
||||
return editor.text;
|
||||
}
|
||||
export function editAsync(text = '', callback, fileOptions) {
|
||||
const editor = new ExternalEditor(text, fileOptions);
|
||||
editor.runAsync((err, result) => {
|
||||
if (err) {
|
||||
setImmediate(callback, err, undefined);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
editor.cleanup();
|
||||
setImmediate(callback, undefined, result);
|
||||
}
|
||||
catch (cleanupError) {
|
||||
setImmediate(callback, cleanupError, undefined);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function sanitizeAffix(affix) {
|
||||
if (!affix)
|
||||
return '';
|
||||
return affix.replace(/[^a-zA-Z0-9_.-]/g, '_');
|
||||
}
|
||||
function splitStringBySpace(str) {
|
||||
const pieces = [];
|
||||
let currentString = '';
|
||||
for (let strIndex = 0; strIndex < str.length; strIndex++) {
|
||||
const currentLetter = str.charAt(strIndex);
|
||||
if (strIndex > 0 &&
|
||||
currentLetter === ' ' &&
|
||||
str[strIndex - 1] !== '\\' &&
|
||||
currentString.length > 0) {
|
||||
pieces.push(currentString);
|
||||
currentString = '';
|
||||
}
|
||||
else {
|
||||
currentString = `${currentString}${currentLetter}`;
|
||||
}
|
||||
}
|
||||
if (currentString.length > 0) {
|
||||
pieces.push(currentString);
|
||||
}
|
||||
return pieces;
|
||||
}
|
||||
export class ExternalEditor {
|
||||
text = '';
|
||||
tempFile;
|
||||
editor;
|
||||
lastExitStatus = 0;
|
||||
fileOptions = {};
|
||||
get temp_file() {
|
||||
console.log('DEPRECATED: temp_file. Use tempFile moving forward.');
|
||||
return this.tempFile;
|
||||
}
|
||||
get last_exit_status() {
|
||||
console.log('DEPRECATED: last_exit_status. Use lastExitStatus moving forward.');
|
||||
return this.lastExitStatus;
|
||||
}
|
||||
constructor(text = '', fileOptions) {
|
||||
this.text = text;
|
||||
if (fileOptions) {
|
||||
this.fileOptions = fileOptions;
|
||||
}
|
||||
this.determineEditor();
|
||||
this.createTemporaryFile();
|
||||
}
|
||||
run() {
|
||||
this.launchEditor();
|
||||
this.readTemporaryFile();
|
||||
return this.text;
|
||||
}
|
||||
runAsync(callback) {
|
||||
try {
|
||||
this.launchEditorAsync(() => {
|
||||
try {
|
||||
this.readTemporaryFile();
|
||||
setImmediate(callback, undefined, this.text);
|
||||
}
|
||||
catch (readError) {
|
||||
setImmediate(callback, readError, undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (launchError) {
|
||||
setImmediate(callback, launchError, undefined);
|
||||
}
|
||||
}
|
||||
cleanup() {
|
||||
this.removeTemporaryFile();
|
||||
}
|
||||
determineEditor() {
|
||||
const editor = process.env['VISUAL']
|
||||
? process.env['VISUAL']
|
||||
: process.env['EDITOR']
|
||||
? process.env['EDITOR']
|
||||
: process.platform.startsWith('win')
|
||||
? 'notepad'
|
||||
: 'vim';
|
||||
const editorOpts = splitStringBySpace(editor).map((piece) => piece.replace('\\ ', ' '));
|
||||
const bin = editorOpts.shift();
|
||||
this.editor = { args: editorOpts, bin };
|
||||
}
|
||||
createTemporaryFile() {
|
||||
try {
|
||||
const baseDir = this.fileOptions.dir ?? os.tmpdir();
|
||||
const id = randomUUID();
|
||||
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
||||
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
||||
const filename = `${prefix}${id}${postfix}`;
|
||||
const candidate = path.resolve(baseDir, filename);
|
||||
const baseResolved = path.resolve(baseDir) + path.sep;
|
||||
if (!candidate.startsWith(baseResolved)) {
|
||||
throw new Error('Resolved temporary file escaped the base directory');
|
||||
}
|
||||
this.tempFile = candidate;
|
||||
const opt = { encoding: 'utf8', flag: 'wx' };
|
||||
if (Object.prototype.hasOwnProperty.call(this.fileOptions, 'mode')) {
|
||||
opt.mode = this.fileOptions.mode;
|
||||
}
|
||||
writeFileSync(this.tempFile, this.text, opt);
|
||||
}
|
||||
catch (createFileError) {
|
||||
throw new CreateFileError(createFileError);
|
||||
}
|
||||
}
|
||||
readTemporaryFile() {
|
||||
try {
|
||||
const tempFileBuffer = readFileSync(this.tempFile);
|
||||
if (tempFileBuffer.length === 0) {
|
||||
this.text = '';
|
||||
}
|
||||
else {
|
||||
let encoding = detect(tempFileBuffer) ?? 'utf8';
|
||||
if (!iconv.encodingExists(encoding)) {
|
||||
// Probably a bad idea, but will at least prevent crashing
|
||||
encoding = 'utf8';
|
||||
}
|
||||
this.text = iconv.decode(tempFileBuffer, encoding);
|
||||
}
|
||||
}
|
||||
catch (readFileError) {
|
||||
throw new ReadFileError(readFileError);
|
||||
}
|
||||
}
|
||||
removeTemporaryFile() {
|
||||
try {
|
||||
unlinkSync(this.tempFile);
|
||||
}
|
||||
catch (removeFileError) {
|
||||
throw new RemoveFileError(removeFileError);
|
||||
}
|
||||
}
|
||||
launchEditor() {
|
||||
try {
|
||||
const editorProcess = spawnSync(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: 'inherit' });
|
||||
this.lastExitStatus = editorProcess.status ?? 0;
|
||||
}
|
||||
catch (launchError) {
|
||||
throw new LaunchEditorError(launchError);
|
||||
}
|
||||
}
|
||||
launchEditorAsync(callback) {
|
||||
try {
|
||||
const editorProcess = spawn(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: 'inherit' });
|
||||
editorProcess.on('exit', (code) => {
|
||||
this.lastExitStatus = code;
|
||||
setImmediate(callback);
|
||||
});
|
||||
}
|
||||
catch (launchError) {
|
||||
throw new LaunchEditorError(launchError);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
node_modules/@inquirer/external-editor/dist/esm/package.json
generated
vendored
Normal file
3
node_modules/@inquirer/external-editor/dist/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
Reference in New Issue
Block a user