@ac-kit/node 0.1.0 → 0.2.0
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/CHANGELOG.md +55 -0
- package/README.md +2 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/net/connection-closed-error.d.ts +12 -0
- package/dist/net/connection-closed-error.d.ts.map +1 -0
- package/dist/net/connection-closed-error.js +15 -0
- package/dist/net/connection-closed-error.js.map +1 -0
- package/dist/net/dgram-socket.d.ts +2 -2
- package/dist/net/dgram-socket.d.ts.map +1 -1
- package/dist/net/dgram-socket.js +35 -35
- package/dist/net/dgram-socket.js.map +1 -1
- package/dist/net/inet-socket.d.ts +64 -0
- package/dist/net/inet-socket.d.ts.map +1 -0
- package/dist/net/inet-socket.js +103 -0
- package/dist/net/inet-socket.js.map +1 -0
- package/dist/net/ipc-server.d.ts +63 -0
- package/dist/net/ipc-server.d.ts.map +1 -0
- package/dist/net/ipc-server.js +75 -0
- package/dist/net/ipc-server.js.map +1 -0
- package/dist/net/ipc-socket.d.ts +55 -22
- package/dist/net/ipc-socket.d.ts.map +1 -1
- package/dist/net/ipc-socket.js +50 -46
- package/dist/net/ipc-socket.js.map +1 -1
- package/dist/net/stream-server.d.ts +80 -0
- package/dist/net/stream-server.d.ts.map +1 -0
- package/dist/net/stream-server.js +129 -0
- package/dist/net/stream-server.js.map +1 -0
- package/dist/net/stream-socket.d.ts +37 -8
- package/dist/net/stream-socket.d.ts.map +1 -1
- package/dist/net/stream-socket.js +80 -27
- package/dist/net/stream-socket.js.map +1 -1
- package/dist/net/tcp-server.d.ts +31 -73
- package/dist/net/tcp-server.d.ts.map +1 -1
- package/dist/net/tcp-server.js +41 -147
- package/dist/net/tcp-server.js.map +1 -1
- package/dist/net/tcp-socket.d.ts +21 -61
- package/dist/net/tcp-socket.d.ts.map +1 -1
- package/dist/net/tcp-socket.js +23 -126
- package/dist/net/tcp-socket.js.map +1 -1
- package/dist/net/tls-server.d.ts +87 -0
- package/dist/net/tls-server.d.ts.map +1 -0
- package/dist/net/tls-server.js +103 -0
- package/dist/net/tls-server.js.map +1 -0
- package/dist/net/tls-socket.d.ts +235 -14
- package/dist/net/tls-socket.d.ts.map +1 -1
- package/dist/net/tls-socket.js +241 -91
- package/dist/net/tls-socket.js.map +1 -1
- package/package.json +4 -4
- package/dist/shell/escape-command-arg.d.ts +0 -9
- package/dist/shell/escape-command-arg.d.ts.map +0 -1
- package/dist/shell/escape-command-arg.js +0 -13
- package/dist/shell/escape-command-arg.js.map +0 -1
- package/dist/shell/escape-command.d.ts +0 -10
- package/dist/shell/escape-command.d.ts.map +0 -1
- package/dist/shell/escape-command.js +0 -12
- package/dist/shell/escape-command.js.map +0 -1
package/dist/net/tls-socket.js
CHANGED
|
@@ -1,146 +1,296 @@
|
|
|
1
1
|
import * as tls from "node:tls";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { nullIfEmpty } from "@ac-kit/core";
|
|
3
|
+
import { ConnectionClosedError } from "./connection-closed-error.js";
|
|
4
|
+
import { InetSocket } from "./inet-socket.js";
|
|
5
|
+
/**
|
|
6
|
+
* TLS socket for establishing encrypted connections to TLS servers.
|
|
7
|
+
*
|
|
8
|
+
* Unlike {@link TcpSocket}, a TLS connection cannot be established on an
|
|
9
|
+
* existing instance: Node.js creates the socket as part of the handshake. The
|
|
10
|
+
* connection therefore starts from the static {@link TlsSocket.connect}, which
|
|
11
|
+
* resolves only once the handshake completed and the peer certificate has been
|
|
12
|
+
* verified.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const socket = await TlsSocket.connect(443, { host: "example.com" });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The same method upgrades an already-connected plaintext stream, which is what
|
|
19
|
+
* `STARTTLS`-style protocols need. The plaintext transport is destroyed if the
|
|
20
|
+
* handshake fails, so a failed upgrade can never fall back to cleartext.
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const plain = TcpSocket.from();
|
|
24
|
+
* await plain.connect(587, { host: "mail.example.com" });
|
|
25
|
+
* // ... negotiate STARTTLS over the plaintext connection ...
|
|
26
|
+
* const secure = await TlsSocket.connect(plain.stream, {
|
|
27
|
+
* servername: "mail.example.com",
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Accessors that report handshake results ({@link TlsSocket.authorized},
|
|
32
|
+
* {@link TlsSocket.getPeerCertificate}, {@link TlsSocket.getCipher}, …) are
|
|
33
|
+
* only meaningful once the handshake completed.
|
|
34
|
+
*/
|
|
35
|
+
export class TlsSocket extends InetSocket {
|
|
36
|
+
/**
|
|
37
|
+
* Wraps an existing stream in a TLS socket without waiting for the handshake.
|
|
38
|
+
*
|
|
39
|
+
* The handshake starts immediately and its outcome is reported through the
|
|
40
|
+
* {@link TlsSocketEvents.secureConnect} and {@link StreamSocketEvents.error}
|
|
41
|
+
* events. Prefer {@link TlsSocket.connect}, which reports both through the
|
|
42
|
+
* returned promise; use this method only to drive the handshake manually.
|
|
43
|
+
*
|
|
44
|
+
* @param stream The plaintext stream to encrypt.
|
|
45
|
+
* @param options Options for the underlying Node.js TLS socket.
|
|
46
|
+
* @returns A new `TlsSocket` instance whose handshake is in progress.
|
|
47
|
+
*/
|
|
5
48
|
static from(stream, options) {
|
|
6
49
|
return new TlsSocket(new tls.TLSSocket(stream, options));
|
|
7
50
|
}
|
|
8
|
-
static connect(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
51
|
+
static async connect(target, options) {
|
|
52
|
+
let connectTarget;
|
|
53
|
+
if (typeof target === "number") {
|
|
54
|
+
connectTarget = { port: target };
|
|
55
|
+
}
|
|
56
|
+
else if (typeof target === "string") {
|
|
57
|
+
connectTarget = { path: target };
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
connectTarget = { socket: target };
|
|
61
|
+
}
|
|
62
|
+
const { signal, ...connectOptions } = { ...options, ...connectTarget };
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
const socket = new TlsSocket(tls.connect(connectOptions));
|
|
65
|
+
try {
|
|
66
|
+
await socket.awaitReady("secureConnect", { signal });
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// Leaving the transport open after a failed upgrade would expose the
|
|
70
|
+
// session to a cleartext downgrade.
|
|
71
|
+
socket.destroy();
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
return socket;
|
|
33
75
|
}
|
|
76
|
+
/** Always `true`; distinguishes a TLS socket from a plaintext one. */
|
|
34
77
|
get encrypted() {
|
|
35
|
-
return this.
|
|
78
|
+
return this.socket.encrypted;
|
|
36
79
|
}
|
|
80
|
+
/** Whether the peer certificate was signed by one of the configured CAs. */
|
|
37
81
|
get authorized() {
|
|
38
|
-
return this.
|
|
82
|
+
return this.socket.authorized;
|
|
39
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Reason why the peer certificate was rejected, or `null` when the peer is
|
|
86
|
+
* authorized or the handshake has not completed yet.
|
|
87
|
+
*/
|
|
40
88
|
get authorizationError() {
|
|
41
|
-
return this.
|
|
89
|
+
return this.socket.authorizationError ?? null;
|
|
42
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Protocol selected through ALPN, or `null` before the handshake completed
|
|
93
|
+
* and when no protocol was negotiated.
|
|
94
|
+
*/
|
|
43
95
|
get alpnProtocol() {
|
|
44
|
-
const value = this.
|
|
96
|
+
const value = this.socket.alpnProtocol;
|
|
97
|
+
return value === false ? null : value;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Server name requested through SNI, or `null` when the peer sent none.
|
|
101
|
+
*
|
|
102
|
+
* Only set on sockets accepted by a server.
|
|
103
|
+
*/
|
|
104
|
+
get servername() {
|
|
105
|
+
const value = this.socket.servername;
|
|
45
106
|
return value === false ? null : value;
|
|
46
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns the local certificate, or `null` when none was presented.
|
|
110
|
+
*
|
|
111
|
+
* @returns The local certificate or `null`.
|
|
112
|
+
*/
|
|
47
113
|
getCertificate() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
114
|
+
// Node.js widens the result to `object` for the empty "no certificate" case.
|
|
115
|
+
return nullIfEmpty(this.socket.getCertificate());
|
|
116
|
+
}
|
|
117
|
+
getPeerCertificate(detailed) {
|
|
118
|
+
return nullIfEmpty(this.socket.getPeerCertificate(detailed));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns the peer certificate as an `X509Certificate`, or `null` when the
|
|
122
|
+
* peer presented none.
|
|
123
|
+
*
|
|
124
|
+
* @returns The peer certificate or `null`.
|
|
125
|
+
*/
|
|
126
|
+
getPeerX509Certificate() {
|
|
127
|
+
return this.socket.getPeerX509Certificate() ?? null;
|
|
57
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns the local certificate as an `X509Certificate`, or `null` when none
|
|
131
|
+
* was presented.
|
|
132
|
+
*
|
|
133
|
+
* @returns The local certificate or `null`.
|
|
134
|
+
*/
|
|
135
|
+
getX509Certificate() {
|
|
136
|
+
return this.socket.getX509Certificate() ?? null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns the negotiated cipher suite.
|
|
140
|
+
*
|
|
141
|
+
* @returns The cipher name, standard name and protocol version.
|
|
142
|
+
*/
|
|
58
143
|
getCipher() {
|
|
59
|
-
return this.
|
|
144
|
+
return this.socket.getCipher();
|
|
60
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Returns the type, name and size of the ephemeral key exchange, or `null`
|
|
148
|
+
* when the key exchange was not ephemeral.
|
|
149
|
+
*
|
|
150
|
+
* @returns The ephemeral key information or `null`.
|
|
151
|
+
*/
|
|
61
152
|
getEphemeralKeyInfo() {
|
|
62
|
-
return this.
|
|
153
|
+
return nullIfEmpty(this.socket.getEphemeralKeyInfo());
|
|
63
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns the latest `Finished` message sent to the peer, or `null` when no
|
|
157
|
+
* handshake completed.
|
|
158
|
+
*
|
|
159
|
+
* @returns The message or `null`.
|
|
160
|
+
*/
|
|
64
161
|
getFinished() {
|
|
65
|
-
|
|
66
|
-
return value ?? null;
|
|
67
|
-
}
|
|
68
|
-
getPeerCertificate(detailed) {
|
|
69
|
-
return this.sock.getPeerCertificate(detailed);
|
|
162
|
+
return this.socket.getFinished() ?? null;
|
|
70
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns the latest `Finished` message received from the peer, or `null`
|
|
166
|
+
* when no handshake completed.
|
|
167
|
+
*
|
|
168
|
+
* @returns The message or `null`.
|
|
169
|
+
*/
|
|
71
170
|
getPeerFinished() {
|
|
72
|
-
|
|
73
|
-
return value ?? null;
|
|
171
|
+
return this.socket.getPeerFinished() ?? null;
|
|
74
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Returns the negotiated protocol version, or `null` before the handshake
|
|
175
|
+
* completed.
|
|
176
|
+
*
|
|
177
|
+
* @returns The protocol version such as `TLSv1.3`, or `null`.
|
|
178
|
+
*/
|
|
75
179
|
getProtocol() {
|
|
76
|
-
return this.
|
|
180
|
+
return this.socket.getProtocol();
|
|
77
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Returns the negotiated session, which can be passed back as the `session`
|
|
184
|
+
* connect option to resume it.
|
|
185
|
+
*
|
|
186
|
+
* @returns The session or `null`.
|
|
187
|
+
*/
|
|
78
188
|
getSession() {
|
|
79
|
-
|
|
80
|
-
return value ?? null;
|
|
189
|
+
return this.socket.getSession() ?? null;
|
|
81
190
|
}
|
|
82
|
-
|
|
83
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Returns the session ticket, or `null` when the peer issued none.
|
|
193
|
+
*
|
|
194
|
+
* @returns The session ticket or `null`.
|
|
195
|
+
*/
|
|
196
|
+
getTLSTicket() {
|
|
197
|
+
return this.socket.getTLSTicket() ?? null;
|
|
84
198
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Returns the signature algorithms shared between client and server, in
|
|
201
|
+
* descending order of preference.
|
|
202
|
+
*
|
|
203
|
+
* @returns The shared signature algorithms.
|
|
204
|
+
*/
|
|
205
|
+
getSharedSigalgs() {
|
|
206
|
+
return this.socket.getSharedSigalgs();
|
|
88
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Indicates whether the session was resumed rather than renegotiated.
|
|
210
|
+
*
|
|
211
|
+
* @returns `true` when the session was reused.
|
|
212
|
+
*/
|
|
89
213
|
isSessionReused() {
|
|
90
|
-
return this.
|
|
214
|
+
return this.socket.isSessionReused();
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Keying material for the connection, as defined by RFC 5705.
|
|
218
|
+
*
|
|
219
|
+
* @param length Number of bytes to derive.
|
|
220
|
+
* @param label Application-specific label.
|
|
221
|
+
* @param context Optional application-specific context.
|
|
222
|
+
* @returns The derived keying material.
|
|
223
|
+
*/
|
|
224
|
+
exportKeyingMaterial(length, label, context) {
|
|
225
|
+
// Node.js accepts an omitted context; @types/node declares it required.
|
|
226
|
+
return this.socket.exportKeyingMaterial(length, label, context);
|
|
91
227
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Renegotiates the TLS session and resolves once the new handshake completed.
|
|
230
|
+
*
|
|
231
|
+
* @param options Renegotiation options.
|
|
232
|
+
* @returns A promise that resolves once renegotiation completed.
|
|
233
|
+
* @throws {ConnectionClosedError} When the socket is already destroyed, since
|
|
234
|
+
* Node.js would never invoke the completion callback.
|
|
235
|
+
*/
|
|
236
|
+
renegotiate(options) {
|
|
237
|
+
if (this.socket.destroyed) {
|
|
238
|
+
throw new ConnectionClosedError("Cannot renegotiate on a destroyed socket");
|
|
96
239
|
}
|
|
97
240
|
return new Promise((resolve, reject) => {
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
reject(
|
|
101
|
-
|
|
102
|
-
else {
|
|
103
|
-
resolve();
|
|
241
|
+
this.socket.renegotiate(options ?? {}, (error) => {
|
|
242
|
+
if (error) {
|
|
243
|
+
reject(error);
|
|
244
|
+
return;
|
|
104
245
|
}
|
|
105
|
-
|
|
106
|
-
|
|
246
|
+
resolve();
|
|
247
|
+
});
|
|
107
248
|
});
|
|
108
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Sets the private key and certificate to use for this socket, overriding the
|
|
252
|
+
* ones inherited from the secure context.
|
|
253
|
+
*
|
|
254
|
+
* @param context The secure context or the options to build one from.
|
|
255
|
+
*/
|
|
109
256
|
setKeyCert(context) {
|
|
110
|
-
this.
|
|
257
|
+
this.socket.setKeyCert(context);
|
|
111
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Sets the maximum TLS fragment size.
|
|
261
|
+
*
|
|
262
|
+
* @param size The maximum fragment size, between 512 and 16384.
|
|
263
|
+
* @returns `true` when the limit was set.
|
|
264
|
+
*/
|
|
112
265
|
setMaxSendFragment(size) {
|
|
113
|
-
return this.
|
|
266
|
+
return this.socket.setMaxSendFragment(size);
|
|
114
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Disables renegotiation. Any further renegotiation attempt by the peer emits
|
|
270
|
+
* an error instead.
|
|
271
|
+
*/
|
|
115
272
|
disableRenegotiation() {
|
|
116
|
-
this.
|
|
273
|
+
this.socket.disableRenegotiation();
|
|
117
274
|
}
|
|
275
|
+
/** Enables OpenSSL trace output on standard error, for debugging. */
|
|
118
276
|
enableTrace() {
|
|
119
|
-
this.
|
|
120
|
-
}
|
|
121
|
-
getPeerX509Certificate() {
|
|
122
|
-
const cert = this.sock.getPeerX509Certificate();
|
|
123
|
-
return cert ?? null;
|
|
124
|
-
}
|
|
125
|
-
getX509Certificate() {
|
|
126
|
-
const cert = this.sock.getX509Certificate();
|
|
127
|
-
return cert ?? null;
|
|
128
|
-
}
|
|
129
|
-
exportKeyingMaterial(length, label, context) {
|
|
130
|
-
return this.sock.exportKeyingMaterial(length, label, context);
|
|
277
|
+
this.socket.enableTrace();
|
|
131
278
|
}
|
|
132
279
|
setupEventForwarding() {
|
|
133
280
|
super.setupEventForwarding();
|
|
134
|
-
this.
|
|
281
|
+
this.socket.on("secureConnect", () => {
|
|
135
282
|
this.dispatch("secureConnect", []);
|
|
136
283
|
});
|
|
137
|
-
this.
|
|
138
|
-
this.dispatch("
|
|
284
|
+
this.socket.on("secure", () => {
|
|
285
|
+
this.dispatch("secure", []);
|
|
286
|
+
});
|
|
287
|
+
this.socket.on("OCSPResponse", (response) => {
|
|
288
|
+
this.dispatch("ocspResponse", [response ?? null]);
|
|
139
289
|
});
|
|
140
|
-
this.
|
|
290
|
+
this.socket.on("keylog", (line) => {
|
|
141
291
|
this.dispatch("keylog", [line]);
|
|
142
292
|
});
|
|
143
|
-
this.
|
|
293
|
+
this.socket.on("session", (session) => {
|
|
144
294
|
this.dispatch("session", [session]);
|
|
145
295
|
});
|
|
146
296
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tls-socket.js","sourceRoot":"","sources":["../../src/net/tls-socket.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tls-socket.js","sourceRoot":"","sources":["../../src/net/tls-socket.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ac-kit/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Node.js extensions and zero-dependency wrappers over node: built-ins — promise-based TCP, TLS, IPC and UDP sockets, file I/O helpers and process utilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fs",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"prepack": "yarn build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@ac-kit/async": "^0.1.
|
|
43
|
-
"@ac-kit/core": "^0.
|
|
42
|
+
"@ac-kit/async": "^0.1.1",
|
|
43
|
+
"@ac-kit/core": "^0.2.0",
|
|
44
44
|
"@types/node": "^26.5.1",
|
|
45
45
|
"type-fest": "^5.8.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@ac-kit/tsconfig": "0.1.0",
|
|
49
49
|
"@ac-kit/typedoc-config": "0.1.0",
|
|
50
|
-
"@ac-kit/vitest-config": "0.1.
|
|
50
|
+
"@ac-kit/vitest-config": "0.1.1",
|
|
51
51
|
"@typescript/native": "typescript@7.0.2",
|
|
52
52
|
"rimraf": "6.1.3",
|
|
53
53
|
"tsx": "4.23.12",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Escape a string to be safely used as a shell argument, using the rules of the
|
|
3
|
-
* current platform.
|
|
4
|
-
*
|
|
5
|
-
* @param expr The string to escape
|
|
6
|
-
* @returns The escaped string
|
|
7
|
-
*/
|
|
8
|
-
export declare const escapeCommandArg: (expr: string) => string;
|
|
9
|
-
//# sourceMappingURL=escape-command-arg.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"escape-command-arg.d.ts","sourceRoot":"","sources":["../../src/shell/escape-command-arg.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAGtB,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { platform as processPlatform } from "node:process";
|
|
2
|
-
import { escapePosixShCommandArg, escapeWin32CmdCommandArg, } from "@ac-kit/core";
|
|
3
|
-
/**
|
|
4
|
-
* Escape a string to be safely used as a shell argument, using the rules of the
|
|
5
|
-
* current platform.
|
|
6
|
-
*
|
|
7
|
-
* @param expr The string to escape
|
|
8
|
-
* @returns The escaped string
|
|
9
|
-
*/
|
|
10
|
-
export const escapeCommandArg = processPlatform === "win32"
|
|
11
|
-
? escapeWin32CmdCommandArg
|
|
12
|
-
: escapePosixShCommandArg;
|
|
13
|
-
//# sourceMappingURL=escape-command-arg.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"escape-command-arg.js","sourceRoot":"","sources":["../../src/shell/escape-command-arg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EACN,uBAAuB,EACvB,wBAAwB,GACxB,MAAM,cAAc,CAAC;AAEtB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAC5B,eAAe,KAAK,OAAO;IAC1B,CAAC,CAAC,wBAAwB;IAC1B,CAAC,CAAC,uBAAuB,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Escapes any characters in a string that might be used to trick a shell
|
|
3
|
-
* command into executing arbitrary commands, using the rules of the current
|
|
4
|
-
* platform.
|
|
5
|
-
*
|
|
6
|
-
* @param cmd The command to escape
|
|
7
|
-
* @returns The escaped command
|
|
8
|
-
*/
|
|
9
|
-
export declare const escapeCommand: (cmd: string) => string;
|
|
10
|
-
//# sourceMappingURL=escape-command.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"escape-command.d.ts","sourceRoot":"","sources":["../../src/shell/escape-command.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAC8B,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { platform as processPlatform } from "node:process";
|
|
2
|
-
import { escapePosixShCommand, escapeWin32CmdCommand } from "@ac-kit/core";
|
|
3
|
-
/**
|
|
4
|
-
* Escapes any characters in a string that might be used to trick a shell
|
|
5
|
-
* command into executing arbitrary commands, using the rules of the current
|
|
6
|
-
* platform.
|
|
7
|
-
*
|
|
8
|
-
* @param cmd The command to escape
|
|
9
|
-
* @returns The escaped command
|
|
10
|
-
*/
|
|
11
|
-
export const escapeCommand = processPlatform === "win32" ? escapeWin32CmdCommand : escapePosixShCommand;
|
|
12
|
-
//# sourceMappingURL=escape-command.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"escape-command.js","sourceRoot":"","sources":["../../src/shell/escape-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE3E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GACzB,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CAAC"}
|