neon 2.47.0 → 3.1.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/README.md +54 -0
- package/dist/_shared/auth_selection.js +76 -79
- package/dist/_shared/credentials.js +166 -187
- package/dist/_shared/env-core/env.js +395 -0
- package/dist/_shared/env-core/reuse-secrets.js +179 -0
- package/dist/_shared/paths.js +129 -126
- package/dist/_shared/profiles.js +192 -242
- package/dist/_shared/secure_file.js +36 -38
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/analytics.js +163 -207
- package/dist/api.js +815 -758
- package/dist/auth.js +121 -141
- package/dist/auth_context.js +39 -53
- package/dist/cli.js +4 -7
- package/dist/commands/api.js +220 -250
- package/dist/commands/api_keys.js +251 -314
- package/dist/commands/auth.js +283 -328
- package/dist/commands/bootstrap.js +372 -437
- package/dist/commands/branches.js +304 -455
- package/dist/commands/bucket.js +374 -514
- package/dist/commands/checkout.js +213 -298
- package/dist/commands/config.js +575 -658
- package/dist/commands/connection_string.js +137 -165
- package/dist/commands/data_api.js +238 -260
- package/dist/commands/databases.js +67 -76
- package/dist/commands/deploy.js +31 -25
- package/dist/commands/dev.js +642 -681
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +243 -303
- package/dist/commands/functions.js +275 -341
- package/dist/commands/index.js +70 -65
- package/dist/commands/init.js +84 -119
- package/dist/commands/inspect.js +55 -55
- package/dist/commands/ip_allow.js +88 -120
- package/dist/commands/link.js +874 -1019
- package/dist/commands/logs.js +291 -0
- package/dist/commands/neon_auth.js +725 -933
- package/dist/commands/operations.js +34 -25
- package/dist/commands/orgs.js +28 -18
- package/dist/commands/profile.js +614 -845
- package/dist/commands/projects.js +313 -373
- package/dist/commands/psql.js +60 -58
- package/dist/commands/roles.js +55 -58
- package/dist/commands/schema_diff.js +87 -131
- package/dist/commands/set_context.js +34 -26
- package/dist/commands/snapshots.js +288 -413
- package/dist/commands/status.js +41 -37
- package/dist/commands/user.js +21 -10
- package/dist/commands/vpc_endpoints.js +85 -113
- package/dist/config.js +7 -6
- package/dist/config_format.js +50 -66
- package/dist/config_template.js +128 -157
- package/dist/context.js +183 -235
- package/dist/current_branch_fast_path.js +40 -49
- package/dist/dev/env.js +313 -394
- package/dist/dev/functions.js +54 -64
- package/dist/dev/inputs.js +46 -58
- package/dist/dev/runtime.js +135 -164
- package/dist/dev/websocket.js +766 -959
- package/dist/env.js +27 -33
- package/dist/env_file.js +118 -132
- package/dist/env_services.js +36 -38
- package/dist/errors.js +57 -68
- package/dist/functions_api.js +45 -43
- package/dist/help.js +189 -140
- package/dist/index.js +182 -257
- package/dist/init/agents.js +137 -118
- package/dist/init/auth.js +58 -68
- package/dist/init/bootstrap.js +325 -396
- package/dist/init/build_config.js +4 -2
- package/dist/init/detect_agent.js +56 -101
- package/dist/init/editors.js +35 -52
- package/dist/init/enrich_output.js +51 -66
- package/dist/init/extension.js +134 -171
- package/dist/init/inspect.js +179 -266
- package/dist/init/interactive.js +510 -622
- package/dist/init/neonctl.js +117 -168
- package/dist/init/orchestrate.js +157 -173
- package/dist/init/phases/auth.js +188 -202
- package/dist/init/phases/cleanup.js +23 -23
- package/dist/init/phases/db.js +251 -277
- package/dist/init/phases/getting_started.js +213 -223
- package/dist/init/phases/mcp.js +174 -224
- package/dist/init/phases/migrations.js +247 -248
- package/dist/init/phases/neon_auth.js +114 -133
- package/dist/init/phases/setup.js +546 -703
- package/dist/init/phases/skills.js +75 -86
- package/dist/init/phases/status.js +72 -67
- package/dist/init/resolve_context.js +102 -99
- package/dist/init/route_command.js +91 -98
- package/dist/init/skills.js +174 -218
- package/dist/init/vsix.js +77 -99
- package/dist/log.js +17 -16
- package/dist/neon_services.js +104 -129
- package/dist/parameters.gen.js +481 -471
- package/dist/pkg.js +17 -19
- package/dist/profile_keys.js +44 -47
- package/dist/psql/cli.js +44 -47
- package/dist/psql/command/cmd_cond.js +231 -406
- package/dist/psql/command/cmd_connect.js +557 -764
- package/dist/psql/command/cmd_copy.js +727 -983
- package/dist/psql/command/cmd_describe.js +1499 -1688
- package/dist/psql/command/cmd_format.js +733 -905
- package/dist/psql/command/cmd_io.js +1293 -2082
- package/dist/psql/command/cmd_lo.js +297 -359
- package/dist/psql/command/cmd_meta.js +727 -878
- package/dist/psql/command/cmd_misc.js +138 -172
- package/dist/psql/command/cmd_pipeline.js +547 -1099
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +261 -325
- package/dist/psql/command/inputQueue.js +35 -33
- package/dist/psql/command/shared.js +49 -63
- package/dist/psql/complete/filenames.js +90 -133
- package/dist/psql/complete/index.js +59 -97
- package/dist/psql/complete/matcher.js +236 -300
- package/dist/psql/complete/psqlVars.js +218 -223
- package/dist/psql/complete/queries.js +159 -177
- package/dist/psql/complete/rules.js +1493 -2299
- package/dist/psql/core/common.js +762 -1180
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1302
- package/dist/psql/core/prompt.js +391 -408
- package/dist/psql/core/settings.js +429 -644
- package/dist/psql/core/sqlHelp.js +480 -554
- package/dist/psql/core/startup.js +626 -815
- package/dist/psql/core/syncVars.js +67 -110
- package/dist/psql/core/variables.js +156 -278
- package/dist/psql/describe/formatters.js +884 -1285
- package/dist/psql/describe/processNamePattern.js +173 -260
- package/dist/psql/describe/queries.js +1368 -2403
- package/dist/psql/describe/versionGate.js +32 -41
- package/dist/psql/index.js +1414 -1927
- package/dist/psql/io/history.js +232 -271
- package/dist/psql/io/input.js +103 -108
- package/dist/psql/io/lineEditor/buffer.js +238 -319
- package/dist/psql/io/lineEditor/complete.js +135 -213
- package/dist/psql/io/lineEditor/filename.js +139 -148
- package/dist/psql/io/lineEditor/index.js +653 -870
- package/dist/psql/io/lineEditor/keymap.js +544 -702
- package/dist/psql/io/lineEditor/vt100.js +294 -341
- package/dist/psql/io/pgpass.js +158 -187
- package/dist/psql/io/pgservice.js +146 -183
- package/dist/psql/io/psqlrc.js +328 -403
- package/dist/psql/print/aligned.js +1020 -1683
- package/dist/psql/print/asciidoc.js +180 -214
- package/dist/psql/print/crosstab.js +281 -442
- package/dist/psql/print/csv.js +48 -70
- package/dist/psql/print/html.js +195 -226
- package/dist/psql/print/json.js +75 -88
- package/dist/psql/print/latex.js +291 -364
- package/dist/psql/print/pager.js +171 -242
- package/dist/psql/print/troff.js +194 -226
- package/dist/psql/print/unaligned.js +69 -95
- package/dist/psql/print/units.js +167 -169
- package/dist/psql/scanner/slash.js +428 -483
- package/dist/psql/scanner/sql.js +445 -889
- package/dist/psql/scanner/stringutils.js +309 -379
- package/dist/psql/types/index.js +2 -7
- package/dist/psql/types/scanner.js +25 -22
- package/dist/psql/wire/connection.js +2042 -2803
- package/dist/psql/wire/copy.js +84 -100
- package/dist/psql/wire/notify.js +39 -59
- package/dist/psql/wire/pipeline.js +305 -518
- package/dist/psql/wire/protocol.js +349 -417
- package/dist/psql/wire/sasl.js +180 -265
- package/dist/psql/wire/tls.js +400 -561
- package/dist/storage_api.js +115 -129
- package/dist/test_utils/fixtures.js +94 -113
- package/dist/test_utils/oauth_server.js +10 -7
- package/dist/test_utils/project_dir.js +33 -0
- package/dist/utils/ai_gateway_notice.js +131 -162
- package/dist/utils/api_enums.js +21 -28
- package/dist/utils/auth.js +10 -4
- package/dist/utils/branch_notice.js +20 -19
- package/dist/utils/branch_picker.js +83 -89
- package/dist/utils/cli_name.js +15 -12
- package/dist/utils/compute_units.js +20 -27
- package/dist/utils/config_diff.js +127 -158
- package/dist/utils/enrichers.js +95 -148
- package/dist/utils/esbuild.js +133 -147
- package/dist/utils/flags.js +35 -47
- package/dist/utils/formats.js +8 -15
- package/dist/utils/git_diff.js +69 -80
- package/dist/utils/inspect_db.js +101 -143
- package/dist/utils/inspect_queries.js +179 -142
- package/dist/utils/middlewares.js +37 -44
- package/dist/utils/openapi.js +87 -99
- package/dist/utils/package_manager.js +312 -110
- package/dist/utils/point_in_time.js +49 -53
- package/dist/utils/psql.js +89 -106
- package/dist/utils/service_picker.js +55 -58
- package/dist/utils/string.js +5 -5
- package/dist/utils/ui.js +38 -55
- package/dist/utils/write_sync.js +26 -35
- package/dist/utils/zip.js +4 -3
- package/dist/writer.js +67 -87
- package/package.json +9 -7
|
@@ -1,363 +1,316 @@
|
|
|
1
|
-
|
|
2
|
-
* VT100/xterm input decoder and CSI escape helpers.
|
|
3
|
-
*
|
|
4
|
-
* Input side: a streaming decoder that consumes raw bytes from stdin and
|
|
5
|
-
* emits `KeyEvent`s. Handles:
|
|
6
|
-
*
|
|
7
|
-
* - Printable ASCII (0x20..0x7e)
|
|
8
|
-
* - Control bytes (0x00..0x1f, plus 0x7f → backspace)
|
|
9
|
-
* - CSI sequences (`\x1b[...`): arrow keys, Home/End, Delete, PageUp/Dn,
|
|
10
|
-
* bracketed paste markers
|
|
11
|
-
* - SS3 sequences (`\x1bO<x>`) for application-mode arrows
|
|
12
|
-
* - Alt-X sequences (`\x1b<letter>`) for Meta keystrokes
|
|
13
|
-
* - Multi-byte UTF-8 codepoints (accumulated until complete)
|
|
14
|
-
*
|
|
15
|
-
* Output side: small helpers wrapping CSI escapes used by the renderer.
|
|
16
|
-
*
|
|
17
|
-
* The decoder is allocation-light: input chunks are appended to a private
|
|
18
|
-
* buffer, then drained from the head. We never throw on malformed input —
|
|
19
|
-
* leftover bytes that can't be decoded become a single `KeyEvent` with
|
|
20
|
-
* `key: 'unknown'` so the editor can ring the bell instead of dying.
|
|
21
|
-
*/
|
|
1
|
+
//#region src/psql/io/lineEditor/vt100.ts
|
|
22
2
|
/** Convenience: build a control-character event for byte `b` in 0x01..0x1f. */
|
|
23
3
|
const controlEvent = (b) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
return {
|
|
5
|
+
key: "char",
|
|
6
|
+
char: String.fromCharCode(b + 96),
|
|
7
|
+
ctrl: true
|
|
8
|
+
};
|
|
27
9
|
};
|
|
28
10
|
/** Streaming decoder. Owns a small pending-byte buffer. */
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const paramStr = String.fromCharCode(...params);
|
|
287
|
-
consume();
|
|
288
|
-
const meta = paramStr.endsWith(";3") || paramStr.endsWith(";7");
|
|
289
|
-
switch (final) {
|
|
290
|
-
case 0x41 /* 'A' */:
|
|
291
|
-
return meta ? { key: "up", meta: true } : { key: "up" };
|
|
292
|
-
case 0x42 /* 'B' */:
|
|
293
|
-
return meta ? { key: "down", meta: true } : { key: "down" };
|
|
294
|
-
case 0x43 /* 'C' */:
|
|
295
|
-
return meta ? { key: "right", meta: true } : { key: "right" };
|
|
296
|
-
case 0x44 /* 'D' */:
|
|
297
|
-
return meta ? { key: "left", meta: true } : { key: "left" };
|
|
298
|
-
case 0x48 /* 'H' */:
|
|
299
|
-
return { key: "home" };
|
|
300
|
-
case 0x46 /* 'F' */:
|
|
301
|
-
return { key: "end" };
|
|
302
|
-
case 0x5a /* 'Z' */:
|
|
303
|
-
// Shift-Tab; treat as plain Tab for now (no reverse cycling yet).
|
|
304
|
-
return { key: "tab", meta: true };
|
|
305
|
-
default:
|
|
306
|
-
return {
|
|
307
|
-
key: "unknown",
|
|
308
|
-
raw: Uint8Array.from(this.pending.slice(0, seqLen)),
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
11
|
+
var Vt100Decoder = class {
|
|
12
|
+
constructor(opts = {}) {
|
|
13
|
+
this.pending = [];
|
|
14
|
+
this.utf8Bytes = [];
|
|
15
|
+
this.utf8Expect = 0;
|
|
16
|
+
this.escTimer = null;
|
|
17
|
+
this.escPending = false;
|
|
18
|
+
this.escTimeoutMs = opts.escTimeoutMs ?? 0;
|
|
19
|
+
this.onTimeoutEvent = opts.onTimeoutEvent;
|
|
20
|
+
}
|
|
21
|
+
/** Reset internal state. Useful before re-entering raw mode after a fork. */
|
|
22
|
+
reset() {
|
|
23
|
+
this.pending.length = 0;
|
|
24
|
+
this.utf8Bytes.length = 0;
|
|
25
|
+
this.utf8Expect = 0;
|
|
26
|
+
this.clearEscTimer();
|
|
27
|
+
this.escPending = false;
|
|
28
|
+
}
|
|
29
|
+
clearEscTimer() {
|
|
30
|
+
if (this.escTimer !== null) {
|
|
31
|
+
clearTimeout(this.escTimer);
|
|
32
|
+
this.escTimer = null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Feed a chunk of input. Returns zero or more `KeyEvent`s; bytes that
|
|
37
|
+
* form an incomplete sequence are buffered until the next call.
|
|
38
|
+
*/
|
|
39
|
+
push(chunk) {
|
|
40
|
+
if (chunk.length > 0 && this.escPending) {
|
|
41
|
+
this.clearEscTimer();
|
|
42
|
+
this.escPending = false;
|
|
43
|
+
}
|
|
44
|
+
for (const b of chunk) this.pending.push(b);
|
|
45
|
+
const out = [];
|
|
46
|
+
for (;;) {
|
|
47
|
+
const before = this.pending.length;
|
|
48
|
+
const ev = this.tryConsume();
|
|
49
|
+
if (ev === null) {
|
|
50
|
+
if (this.pending.length !== before) continue;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
out.push(ev);
|
|
54
|
+
if (this.pending.length === 0) break;
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Try to consume one key sequence from the head of `pending`. Returns
|
|
60
|
+
* the event, or `null` if more input is needed. May consume bytes
|
|
61
|
+
* without emitting (UTF-8 lead byte → continuation).
|
|
62
|
+
*/
|
|
63
|
+
tryConsume() {
|
|
64
|
+
if (this.pending.length === 0) return null;
|
|
65
|
+
const b = this.pending[0];
|
|
66
|
+
if (this.utf8Expect > 0) {
|
|
67
|
+
if ((b & 192) !== 128) {
|
|
68
|
+
this.utf8Bytes.length = 0;
|
|
69
|
+
this.utf8Expect = 0;
|
|
70
|
+
this.pending.shift();
|
|
71
|
+
return {
|
|
72
|
+
key: "unknown",
|
|
73
|
+
raw: new Uint8Array([b])
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
this.utf8Bytes.push(b);
|
|
77
|
+
this.pending.shift();
|
|
78
|
+
this.utf8Expect--;
|
|
79
|
+
if (this.utf8Expect === 0) {
|
|
80
|
+
const bytes = Uint8Array.from(this.utf8Bytes);
|
|
81
|
+
this.utf8Bytes.length = 0;
|
|
82
|
+
return {
|
|
83
|
+
key: "char",
|
|
84
|
+
char: utf8Decode(bytes)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if (b >= 32 && b <= 126) {
|
|
90
|
+
this.pending.shift();
|
|
91
|
+
return {
|
|
92
|
+
key: "char",
|
|
93
|
+
char: String.fromCharCode(b)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (b === 9) {
|
|
97
|
+
this.pending.shift();
|
|
98
|
+
return { key: "tab" };
|
|
99
|
+
}
|
|
100
|
+
if (b === 10 || b === 13) {
|
|
101
|
+
this.pending.shift();
|
|
102
|
+
return { key: "enter" };
|
|
103
|
+
}
|
|
104
|
+
if (b === 127 || b === 8) {
|
|
105
|
+
this.pending.shift();
|
|
106
|
+
return { key: "backspace" };
|
|
107
|
+
}
|
|
108
|
+
if (b === 27) return this.consumeEscape();
|
|
109
|
+
if (b < 32) {
|
|
110
|
+
this.pending.shift();
|
|
111
|
+
return controlEvent(b);
|
|
112
|
+
}
|
|
113
|
+
if ((b & 224) === 192) {
|
|
114
|
+
this.utf8Expect = 1;
|
|
115
|
+
this.utf8Bytes = [b];
|
|
116
|
+
this.pending.shift();
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if ((b & 240) === 224) {
|
|
120
|
+
this.utf8Expect = 2;
|
|
121
|
+
this.utf8Bytes = [b];
|
|
122
|
+
this.pending.shift();
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if ((b & 248) === 240) {
|
|
126
|
+
this.utf8Expect = 3;
|
|
127
|
+
this.utf8Bytes = [b];
|
|
128
|
+
this.pending.shift();
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
this.pending.shift();
|
|
132
|
+
return {
|
|
133
|
+
key: "unknown",
|
|
134
|
+
raw: new Uint8Array([b])
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Called when the head byte is 0x1b. Tries to consume an escape
|
|
139
|
+
* sequence; returns `null` if more bytes are needed.
|
|
140
|
+
*
|
|
141
|
+
* When only the Esc byte sits in the buffer we have two strategies:
|
|
142
|
+
*
|
|
143
|
+
* 1) `escTimeoutMs === 0` (default for non-LineEditor callers): emit
|
|
144
|
+
* the bare `escape` immediately. Matches the pre-polish behaviour.
|
|
145
|
+
* 2) `escTimeoutMs > 0`: park the Esc byte, arm a `setTimeout`. If a
|
|
146
|
+
* follow-on byte arrives within the window, `push()` cancels the
|
|
147
|
+
* timer and the normal Esc-prefix path runs. Otherwise the timer
|
|
148
|
+
* fires and we synthesise an `escape` event into the host queue.
|
|
149
|
+
*/
|
|
150
|
+
consumeEscape() {
|
|
151
|
+
if (this.pending.length === 1) {
|
|
152
|
+
if (this.escTimeoutMs === 0) {
|
|
153
|
+
this.pending.shift();
|
|
154
|
+
return { key: "escape" };
|
|
155
|
+
}
|
|
156
|
+
if (this.escPending) return null;
|
|
157
|
+
this.escPending = true;
|
|
158
|
+
this.escTimer = setTimeout(() => {
|
|
159
|
+
this.escTimer = null;
|
|
160
|
+
if (this.escPending && this.pending[0] === 27) {
|
|
161
|
+
this.pending.shift();
|
|
162
|
+
this.escPending = false;
|
|
163
|
+
this.onTimeoutEvent?.({ key: "escape" });
|
|
164
|
+
} else this.escPending = false;
|
|
165
|
+
}, this.escTimeoutMs);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const b1 = this.pending[1];
|
|
169
|
+
if (b1 === 91) return this.consumeCsi();
|
|
170
|
+
if (b1 === 79) {
|
|
171
|
+
if (this.pending.length < 3) return null;
|
|
172
|
+
const b2 = this.pending[2];
|
|
173
|
+
this.pending.splice(0, 3);
|
|
174
|
+
return ss3ToEvent(b2);
|
|
175
|
+
}
|
|
176
|
+
if (b1 < 32) {
|
|
177
|
+
this.pending.splice(0, 2);
|
|
178
|
+
const inner = controlEvent(b1);
|
|
179
|
+
inner.meta = true;
|
|
180
|
+
return inner;
|
|
181
|
+
}
|
|
182
|
+
if (b1 === 127) {
|
|
183
|
+
this.pending.splice(0, 2);
|
|
184
|
+
return {
|
|
185
|
+
key: "backspace",
|
|
186
|
+
meta: true
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (b1 >= 32 && b1 <= 126) {
|
|
190
|
+
this.pending.splice(0, 2);
|
|
191
|
+
return {
|
|
192
|
+
key: "char",
|
|
193
|
+
char: String.fromCharCode(b1),
|
|
194
|
+
meta: true
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const raw = Uint8Array.from(this.pending.slice(0, 2));
|
|
198
|
+
this.pending.splice(0, 2);
|
|
199
|
+
return {
|
|
200
|
+
key: "unknown",
|
|
201
|
+
raw
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
consumeCsi() {
|
|
205
|
+
let i = 2;
|
|
206
|
+
while (i < this.pending.length) {
|
|
207
|
+
const b = this.pending[i];
|
|
208
|
+
if (b >= 64 && b <= 126) break;
|
|
209
|
+
i++;
|
|
210
|
+
}
|
|
211
|
+
if (i === this.pending.length) return null;
|
|
212
|
+
const params = this.pending.slice(2, i);
|
|
213
|
+
const final = this.pending[i];
|
|
214
|
+
const seqLen = i + 1;
|
|
215
|
+
const consume = () => {
|
|
216
|
+
this.pending.splice(0, seqLen);
|
|
217
|
+
};
|
|
218
|
+
if (final === 126) {
|
|
219
|
+
const paramStr = String.fromCharCode(...params);
|
|
220
|
+
consume();
|
|
221
|
+
switch (paramStr) {
|
|
222
|
+
case "1":
|
|
223
|
+
case "7": return { key: "home" };
|
|
224
|
+
case "2": return { key: "unknown" };
|
|
225
|
+
case "3": return { key: "delete" };
|
|
226
|
+
case "4":
|
|
227
|
+
case "8": return { key: "end" };
|
|
228
|
+
case "5": return { key: "pageup" };
|
|
229
|
+
case "6": return { key: "pagedown" };
|
|
230
|
+
case "200": return { key: "paste-start" };
|
|
231
|
+
case "201": return { key: "paste-end" };
|
|
232
|
+
default: return { key: "unknown" };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const paramStr = String.fromCharCode(...params);
|
|
236
|
+
consume();
|
|
237
|
+
const meta = paramStr.endsWith(";3") || paramStr.endsWith(";7");
|
|
238
|
+
switch (final) {
|
|
239
|
+
case 65: return meta ? {
|
|
240
|
+
key: "up",
|
|
241
|
+
meta: true
|
|
242
|
+
} : { key: "up" };
|
|
243
|
+
case 66: return meta ? {
|
|
244
|
+
key: "down",
|
|
245
|
+
meta: true
|
|
246
|
+
} : { key: "down" };
|
|
247
|
+
case 67: return meta ? {
|
|
248
|
+
key: "right",
|
|
249
|
+
meta: true
|
|
250
|
+
} : { key: "right" };
|
|
251
|
+
case 68: return meta ? {
|
|
252
|
+
key: "left",
|
|
253
|
+
meta: true
|
|
254
|
+
} : { key: "left" };
|
|
255
|
+
case 72: return { key: "home" };
|
|
256
|
+
case 70: return { key: "end" };
|
|
257
|
+
case 90: return {
|
|
258
|
+
key: "tab",
|
|
259
|
+
meta: true
|
|
260
|
+
};
|
|
261
|
+
default: return {
|
|
262
|
+
key: "unknown",
|
|
263
|
+
raw: Uint8Array.from(this.pending.slice(0, seqLen))
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
};
|
|
313
268
|
/** Decode a small UTF-8 byte sequence (1..4 bytes) into a string. */
|
|
314
269
|
const utf8Decode = (bytes) => {
|
|
315
|
-
|
|
316
|
-
return new TextDecoder("utf-8", { fatal: false }).decode(bytes);
|
|
270
|
+
return new TextDecoder("utf-8", { fatal: false }).decode(bytes);
|
|
317
271
|
};
|
|
318
272
|
/** Translate an SS3 final byte (after `ESC O`) into a key event. */
|
|
319
273
|
const ss3ToEvent = (b) => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
274
|
+
switch (b) {
|
|
275
|
+
case 65: return { key: "up" };
|
|
276
|
+
case 66: return { key: "down" };
|
|
277
|
+
case 67: return { key: "right" };
|
|
278
|
+
case 68: return { key: "left" };
|
|
279
|
+
case 72: return { key: "home" };
|
|
280
|
+
case 70: return { key: "end" };
|
|
281
|
+
default: return {
|
|
282
|
+
key: "unknown",
|
|
283
|
+
raw: new Uint8Array([
|
|
284
|
+
27,
|
|
285
|
+
79,
|
|
286
|
+
b
|
|
287
|
+
])
|
|
288
|
+
};
|
|
289
|
+
}
|
|
336
290
|
};
|
|
337
|
-
// ---------------------------------------------------------------------------
|
|
338
|
-
// CSI output helpers
|
|
339
|
-
// ---------------------------------------------------------------------------
|
|
340
291
|
/** Move cursor up N rows. */
|
|
341
|
-
|
|
292
|
+
const csiUp = (n) => n > 0 ? `\x1b[${n}A` : "";
|
|
342
293
|
/** Move cursor down N rows. */
|
|
343
|
-
|
|
294
|
+
const csiDown = (n) => n > 0 ? `\x1b[${n}B` : "";
|
|
344
295
|
/** Move cursor right N columns. */
|
|
345
|
-
|
|
296
|
+
const csiRight = (n) => n > 0 ? `\x1b[${n}C` : "";
|
|
346
297
|
/** Move cursor left N columns. */
|
|
347
|
-
|
|
298
|
+
const csiLeft = (n) => n > 0 ? `\x1b[${n}D` : "";
|
|
348
299
|
/** Move cursor to column N (1-based). */
|
|
349
|
-
|
|
300
|
+
const csiToColumn = (col) => `\x1b[${col}G`;
|
|
350
301
|
/** Erase from cursor to end-of-line. */
|
|
351
|
-
|
|
302
|
+
const csiEraseToEol = () => "\x1B[K";
|
|
352
303
|
/** Erase entire screen and move cursor to home. */
|
|
353
|
-
|
|
304
|
+
const csiClearScreen = () => "\x1B[2J\x1B[H";
|
|
354
305
|
/** Carriage return: move to column 1 without writing a newline. */
|
|
355
|
-
|
|
306
|
+
const CR = "\r";
|
|
356
307
|
/** Newline (LF). */
|
|
357
|
-
|
|
308
|
+
const LF = "\n";
|
|
358
309
|
/** Enable bracketed paste mode (DEC private mode 2004). */
|
|
359
|
-
|
|
310
|
+
const enableBracketedPaste = () => "\x1B[?2004h";
|
|
360
311
|
/** Disable bracketed paste mode. */
|
|
361
|
-
|
|
312
|
+
const disableBracketedPaste = () => "\x1B[?2004l";
|
|
362
313
|
/** Audible bell. */
|
|
363
|
-
|
|
314
|
+
const BEL = "\x07";
|
|
315
|
+
//#endregion
|
|
316
|
+
export { BEL, CR, LF, Vt100Decoder, csiClearScreen, csiDown, csiEraseToEol, csiLeft, csiRight, csiToColumn, csiUp, disableBracketedPaste, enableBracketedPaste };
|