@cjser/inquirer__external-editor 3.0.2-cjser.2 → 3.0.4-cjser.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27 -14
- package/dist-cjser/index.cjs +30 -17
- package/package.json +6 -5
- package/dist/errors/CreateFileError.d.ts +0 -10
- package/dist/errors/CreateFileError.js +0 -13
- package/dist/errors/LaunchEditorError.d.ts +0 -10
- package/dist/errors/LaunchEditorError.js +0 -13
- package/dist/errors/ReadFileError.d.ts +0 -10
- package/dist/errors/ReadFileError.js +0 -13
- package/dist/errors/RemoveFileError.d.ts +0 -10
- package/dist/errors/RemoveFileError.js +0 -13
package/README.md
CHANGED
|
@@ -77,6 +77,19 @@ try {
|
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
### Windows editor commands
|
|
81
|
+
|
|
82
|
+
On Windows, prefer setting `$VISUAL` or `$EDITOR` to the editor executable
|
|
83
|
+
rather than a `.cmd` or `.bat` shim. This package launches the editor directly
|
|
84
|
+
instead of through a shell so editor arguments and temporary file paths are not
|
|
85
|
+
interpreted as shell commands.
|
|
86
|
+
|
|
87
|
+
For example, use `Code.exe` with `--wait` instead of `code.cmd`:
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
setx VISUAL '"C:\Program Files\Microsoft VS Code\Code.exe" --wait'
|
|
91
|
+
```
|
|
92
|
+
|
|
80
93
|
#### API
|
|
81
94
|
|
|
82
95
|
**Convenience Functions**
|
package/dist/index.d.ts
CHANGED
|
@@ -23,11 +23,13 @@ export declare class ExternalEditor {
|
|
|
23
23
|
lastExitStatus: number;
|
|
24
24
|
private text;
|
|
25
25
|
private tempFile;
|
|
26
|
+
private tempDir;
|
|
26
27
|
private fileOptions;
|
|
27
28
|
constructor(text?: string, fileOptions?: FileOptions);
|
|
28
29
|
run(): string;
|
|
29
30
|
runAsync(callback?: StringCallback): Promise<string>;
|
|
30
31
|
private cleanup;
|
|
31
32
|
private createTempFile;
|
|
33
|
+
private editorArgs;
|
|
32
34
|
private readTemporaryFile;
|
|
33
35
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { detect } from 'chardet';
|
|
2
2
|
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
-
import { readFileSync,
|
|
3
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import { randomUUID } from 'node:crypto';
|
|
@@ -26,6 +26,7 @@ export class ExternalEditor {
|
|
|
26
26
|
lastExitStatus = 0;
|
|
27
27
|
text = '';
|
|
28
28
|
tempFile = '';
|
|
29
|
+
tempDir = '';
|
|
29
30
|
fileOptions = {};
|
|
30
31
|
constructor(text = '', fileOptions = {}) {
|
|
31
32
|
this.text = text;
|
|
@@ -38,7 +39,13 @@ export class ExternalEditor {
|
|
|
38
39
|
this.createTempFile();
|
|
39
40
|
try {
|
|
40
41
|
try {
|
|
41
|
-
const editorProcess = spawnSync(this.editor.bin, this.
|
|
42
|
+
const editorProcess = spawnSync(this.editor.bin, this.editorArgs(), {
|
|
43
|
+
shell: false,
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
});
|
|
46
|
+
if (editorProcess.error) {
|
|
47
|
+
throw editorProcess.error;
|
|
48
|
+
}
|
|
42
49
|
this.lastExitStatus = editorProcess.status ?? 0;
|
|
43
50
|
}
|
|
44
51
|
catch (launchError) {
|
|
@@ -55,9 +62,15 @@ export class ExternalEditor {
|
|
|
55
62
|
this.createTempFile();
|
|
56
63
|
const promise = new Promise((resolve, reject) => {
|
|
57
64
|
try {
|
|
58
|
-
const editorProcess = spawn(this.editor.bin, this.
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
const editorProcess = spawn(this.editor.bin, this.editorArgs(), {
|
|
66
|
+
shell: false,
|
|
67
|
+
stdio: 'inherit',
|
|
68
|
+
});
|
|
69
|
+
editorProcess.once('error', (launchError) => {
|
|
70
|
+
reject(new LaunchEditorError(launchError));
|
|
71
|
+
});
|
|
72
|
+
editorProcess.once('exit', (code) => {
|
|
73
|
+
this.lastExitStatus = code ?? 0;
|
|
61
74
|
resolve();
|
|
62
75
|
});
|
|
63
76
|
}
|
|
@@ -78,11 +91,12 @@ export class ExternalEditor {
|
|
|
78
91
|
return promise;
|
|
79
92
|
}
|
|
80
93
|
cleanup() {
|
|
81
|
-
if (!this.
|
|
94
|
+
if (!this.tempDir)
|
|
82
95
|
return;
|
|
83
96
|
try {
|
|
84
|
-
|
|
97
|
+
rmSync(this.tempDir, { force: true, recursive: true });
|
|
85
98
|
this.tempFile = '';
|
|
99
|
+
this.tempDir = '';
|
|
86
100
|
}
|
|
87
101
|
catch (removeFileError) {
|
|
88
102
|
throw new RemoveFileError(removeFileError);
|
|
@@ -90,17 +104,13 @@ export class ExternalEditor {
|
|
|
90
104
|
}
|
|
91
105
|
createTempFile() {
|
|
92
106
|
try {
|
|
93
|
-
const baseDir = this.fileOptions.dir ?? os.tmpdir();
|
|
107
|
+
const baseDir = path.resolve(this.fileOptions.dir ?? os.tmpdir());
|
|
108
|
+
this.tempDir = mkdtempSync(path.join(baseDir, 'inquirer-editor-'));
|
|
94
109
|
const id = randomUUID();
|
|
95
110
|
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
|
96
111
|
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
|
97
112
|
const filename = `${prefix}${id}${postfix}`;
|
|
98
|
-
|
|
99
|
-
const baseResolved = path.resolve(baseDir) + path.sep;
|
|
100
|
-
if (!candidate.startsWith(baseResolved)) {
|
|
101
|
-
throw new Error('Resolved temporary file escaped the base directory');
|
|
102
|
-
}
|
|
103
|
-
this.tempFile = candidate;
|
|
113
|
+
this.tempFile = path.join(this.tempDir, filename);
|
|
104
114
|
const opt = { encoding: 'utf8', flag: 'wx' };
|
|
105
115
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, 'mode')) {
|
|
106
116
|
opt.mode = this.fileOptions.mode;
|
|
@@ -111,6 +121,9 @@ export class ExternalEditor {
|
|
|
111
121
|
throw new CreateFileError(createFileError);
|
|
112
122
|
}
|
|
113
123
|
}
|
|
124
|
+
editorArgs() {
|
|
125
|
+
return [...this.editor.args, this.tempFile];
|
|
126
|
+
}
|
|
114
127
|
readTemporaryFile() {
|
|
115
128
|
try {
|
|
116
129
|
const tempFileBuffer = readFileSync(this.tempFile);
|
package/dist-cjser/index.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
-
// packages/@cjser/inquirer__external-editor.tmp-25-
|
|
29
|
+
// packages/@cjser/inquirer__external-editor.tmp-25-1788288342955/dist/index.js
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
CreateFileError: () => CreateFileError,
|
|
@@ -46,7 +46,7 @@ var import_node_os = __toESM(require("node:os"), 1);
|
|
|
46
46
|
var import_node_crypto = require("node:crypto");
|
|
47
47
|
var import_iconv_lite = __toESM(require("iconv-lite"), 1);
|
|
48
48
|
|
|
49
|
-
// packages/@cjser/inquirer__external-editor.tmp-25-
|
|
49
|
+
// packages/@cjser/inquirer__external-editor.tmp-25-1788288342955/dist/errors.js
|
|
50
50
|
var CreateFileError = class extends Error {
|
|
51
51
|
name = "CreateFileError";
|
|
52
52
|
originalError;
|
|
@@ -80,7 +80,7 @@ var RemoveFileError = class extends Error {
|
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
// packages/@cjser/inquirer__external-editor.tmp-25-
|
|
83
|
+
// packages/@cjser/inquirer__external-editor.tmp-25-1788288342955/dist/parse-editor-command.js
|
|
84
84
|
function parseEditorCommand(editor) {
|
|
85
85
|
let bin;
|
|
86
86
|
let rest;
|
|
@@ -106,7 +106,7 @@ function parseEditorCommand(editor) {
|
|
|
106
106
|
return { bin, args: rest ? rest.split(/\s+/) : [] };
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// packages/@cjser/inquirer__external-editor.tmp-25-
|
|
109
|
+
// packages/@cjser/inquirer__external-editor.tmp-25-1788288342955/dist/index.js
|
|
110
110
|
function edit(text = "", fileOptions) {
|
|
111
111
|
return new ExternalEditor(text, fileOptions).run();
|
|
112
112
|
}
|
|
@@ -125,6 +125,7 @@ var ExternalEditor = class {
|
|
|
125
125
|
lastExitStatus = 0;
|
|
126
126
|
text = "";
|
|
127
127
|
tempFile = "";
|
|
128
|
+
tempDir = "";
|
|
128
129
|
fileOptions = {};
|
|
129
130
|
constructor(text = "", fileOptions = {}) {
|
|
130
131
|
this.text = text;
|
|
@@ -135,7 +136,13 @@ var ExternalEditor = class {
|
|
|
135
136
|
this.createTempFile();
|
|
136
137
|
try {
|
|
137
138
|
try {
|
|
138
|
-
const editorProcess = (0, import_node_child_process.spawnSync)(this.editor.bin, this.
|
|
139
|
+
const editorProcess = (0, import_node_child_process.spawnSync)(this.editor.bin, this.editorArgs(), {
|
|
140
|
+
shell: false,
|
|
141
|
+
stdio: "inherit"
|
|
142
|
+
});
|
|
143
|
+
if (editorProcess.error) {
|
|
144
|
+
throw editorProcess.error;
|
|
145
|
+
}
|
|
139
146
|
this.lastExitStatus = editorProcess.status ?? 0;
|
|
140
147
|
} catch (launchError) {
|
|
141
148
|
throw new LaunchEditorError(launchError);
|
|
@@ -150,9 +157,15 @@ var ExternalEditor = class {
|
|
|
150
157
|
this.createTempFile();
|
|
151
158
|
const promise = new Promise((resolve, reject) => {
|
|
152
159
|
try {
|
|
153
|
-
const editorProcess = (0, import_node_child_process.spawn)(this.editor.bin, this.
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
const editorProcess = (0, import_node_child_process.spawn)(this.editor.bin, this.editorArgs(), {
|
|
161
|
+
shell: false,
|
|
162
|
+
stdio: "inherit"
|
|
163
|
+
});
|
|
164
|
+
editorProcess.once("error", (launchError) => {
|
|
165
|
+
reject(new LaunchEditorError(launchError));
|
|
166
|
+
});
|
|
167
|
+
editorProcess.once("exit", (code) => {
|
|
168
|
+
this.lastExitStatus = code ?? 0;
|
|
156
169
|
resolve();
|
|
157
170
|
});
|
|
158
171
|
} catch (launchError) {
|
|
@@ -170,28 +183,25 @@ var ExternalEditor = class {
|
|
|
170
183
|
return promise;
|
|
171
184
|
}
|
|
172
185
|
cleanup() {
|
|
173
|
-
if (!this.
|
|
186
|
+
if (!this.tempDir)
|
|
174
187
|
return;
|
|
175
188
|
try {
|
|
176
|
-
(0, import_node_fs.
|
|
189
|
+
(0, import_node_fs.rmSync)(this.tempDir, { force: true, recursive: true });
|
|
177
190
|
this.tempFile = "";
|
|
191
|
+
this.tempDir = "";
|
|
178
192
|
} catch (removeFileError) {
|
|
179
193
|
throw new RemoveFileError(removeFileError);
|
|
180
194
|
}
|
|
181
195
|
}
|
|
182
196
|
createTempFile() {
|
|
183
197
|
try {
|
|
184
|
-
const baseDir = this.fileOptions.dir ?? import_node_os.default.tmpdir();
|
|
198
|
+
const baseDir = import_node_path.default.resolve(this.fileOptions.dir ?? import_node_os.default.tmpdir());
|
|
199
|
+
this.tempDir = (0, import_node_fs.mkdtempSync)(import_node_path.default.join(baseDir, "inquirer-editor-"));
|
|
185
200
|
const id = (0, import_node_crypto.randomUUID)();
|
|
186
201
|
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
|
187
202
|
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
|
188
203
|
const filename = `${prefix}${id}${postfix}`;
|
|
189
|
-
|
|
190
|
-
const baseResolved = import_node_path.default.resolve(baseDir) + import_node_path.default.sep;
|
|
191
|
-
if (!candidate.startsWith(baseResolved)) {
|
|
192
|
-
throw new Error("Resolved temporary file escaped the base directory");
|
|
193
|
-
}
|
|
194
|
-
this.tempFile = candidate;
|
|
204
|
+
this.tempFile = import_node_path.default.join(this.tempDir, filename);
|
|
195
205
|
const opt = { encoding: "utf8", flag: "wx" };
|
|
196
206
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
197
207
|
opt.mode = this.fileOptions.mode;
|
|
@@ -201,6 +211,9 @@ var ExternalEditor = class {
|
|
|
201
211
|
throw new CreateFileError(createFileError);
|
|
202
212
|
}
|
|
203
213
|
}
|
|
214
|
+
editorArgs() {
|
|
215
|
+
return [...this.editor.args, this.tempFile];
|
|
216
|
+
}
|
|
204
217
|
readTemporaryFile() {
|
|
205
218
|
try {
|
|
206
219
|
const tempFileBuffer = (0, import_node_fs.readFileSync)(this.tempFile);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cjser/inquirer__external-editor",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.4-cjser.2",
|
|
4
4
|
"description": "Edit a string with the users preferred text editor using $VISUAL or $ENVIRONMENT",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"answer",
|
|
@@ -78,8 +78,9 @@
|
|
|
78
78
|
"iconv-lite": "^0.7.2"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
+
"@repo/tsconfig": "0.0.0",
|
|
81
82
|
"@types/chardet": "^1.0.0",
|
|
82
|
-
"@types/node": "^
|
|
83
|
+
"@types/node": "^26.1.1",
|
|
83
84
|
"typescript": "^6.0.2"
|
|
84
85
|
},
|
|
85
86
|
"peerDependencies": {
|
|
@@ -95,13 +96,13 @@
|
|
|
95
96
|
},
|
|
96
97
|
"main": "./dist-cjser/index.cjs",
|
|
97
98
|
"types": "./dist/index.d.ts",
|
|
98
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "999706755afbdcae271f62decbd9bcd05560905b",
|
|
99
100
|
"cjser": {
|
|
100
|
-
"sourceVersion": "3.0.
|
|
101
|
+
"sourceVersion": "3.0.4",
|
|
101
102
|
"cjserVersion": 2,
|
|
102
103
|
"original": {
|
|
103
104
|
"name": "@inquirer/external-editor",
|
|
104
|
-
"version": "3.0.
|
|
105
|
+
"version": "3.0.4",
|
|
105
106
|
"main": "./dist/index.js",
|
|
106
107
|
"exports": {
|
|
107
108
|
".": {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/***
|
|
2
|
-
* Node External Editor
|
|
3
|
-
*
|
|
4
|
-
* Kevin Gravier <kevin@mrkmg.com>
|
|
5
|
-
* MIT 2018
|
|
6
|
-
*/
|
|
7
|
-
export class CreateFileError extends Error {
|
|
8
|
-
originalError;
|
|
9
|
-
constructor(originalError) {
|
|
10
|
-
super(`Failed to create temporary file. ${originalError.message}`);
|
|
11
|
-
this.originalError = originalError;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/***
|
|
2
|
-
* Node External Editor
|
|
3
|
-
*
|
|
4
|
-
* Kevin Gravier <kevin@mrkmg.com>
|
|
5
|
-
* MIT 2018
|
|
6
|
-
*/
|
|
7
|
-
export class LaunchEditorError extends Error {
|
|
8
|
-
originalError;
|
|
9
|
-
constructor(originalError) {
|
|
10
|
-
super(`Failed to launch editor. ${originalError.message}`);
|
|
11
|
-
this.originalError = originalError;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/***
|
|
2
|
-
* Node External Editor
|
|
3
|
-
*
|
|
4
|
-
* Kevin Gravier <kevin@mrkmg.com>
|
|
5
|
-
* MIT 2018
|
|
6
|
-
*/
|
|
7
|
-
export class ReadFileError extends Error {
|
|
8
|
-
originalError;
|
|
9
|
-
constructor(originalError) {
|
|
10
|
-
super(`Failed to read temporary file. ${originalError.message}`);
|
|
11
|
-
this.originalError = originalError;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/***
|
|
2
|
-
* Node External Editor
|
|
3
|
-
*
|
|
4
|
-
* Kevin Gravier <kevin@mrkmg.com>
|
|
5
|
-
* MIT 2018
|
|
6
|
-
*/
|
|
7
|
-
export class RemoveFileError extends Error {
|
|
8
|
-
originalError;
|
|
9
|
-
constructor(originalError) {
|
|
10
|
-
super(`Failed to remove temporary file. ${originalError.message}`);
|
|
11
|
-
this.originalError = originalError;
|
|
12
|
-
}
|
|
13
|
-
}
|