@lingxia/types 0.11.1 → 0.12.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/dist/automation/index.d.ts +289 -3
- package/dist/automation/index.d.ts.map +1 -1
- package/dist/automation-test-globals.d.ts +14 -0
- package/dist/error.d.ts +13 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +47 -1
- package/dist/error.js.map +1 -1
- package/dist/generated/i18n.d.ts +1 -1
- package/dist/generated/i18n.d.ts.map +1 -1
- package/dist/generated/i18n.js +8 -0
- package/dist/generated/i18n.js.map +1 -1
- package/dist/generated/logic.d.ts +1055 -462
- package/dist/generated/logic.d.ts.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/testing/public-api.d.ts +429 -0
- package/dist/testing/public-api.d.ts.map +1 -0
- package/dist/testing/public-api.js +588 -0
- package/dist/testing/public-api.js.map +1 -0
- package/dist/testing/public-api.mjs +584 -0
- package/package.json +12 -3
- package/src/automation/index.ts +299 -3
- package/src/error.ts +47 -1
- package/src/generated/i18n.ts +8 -0
- package/src/generated/logic.ts +1117 -487
- package/src/index.ts +16 -0
- package/src/testing/public-api.ts +716 -0
package/src/automation/index.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* product-side API.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import type { TerminalSettingsValue } from '../generated/logic.js';
|
|
13
|
+
|
|
12
14
|
// ============================ factory ============================
|
|
13
15
|
|
|
14
16
|
/** Stable automation root; it grants no capability until one is selected. */
|
|
@@ -21,6 +23,8 @@ export interface Automation {
|
|
|
21
23
|
readonly lxapps: LxAppManager;
|
|
22
24
|
/** The host app's browser tabs. */
|
|
23
25
|
readonly browser: BrowserDriver;
|
|
26
|
+
/** Persisted host-shell shortcuts for deterministic test setup/assertion. */
|
|
27
|
+
readonly shell: ShellDriver;
|
|
24
28
|
/** Simulated-device selection in a host runner. */
|
|
25
29
|
readonly device: DeviceDriver;
|
|
26
30
|
/**
|
|
@@ -29,6 +33,141 @@ export interface Automation {
|
|
|
29
33
|
* Runner) on top of the `host` privilege. Windows/macOS only.
|
|
30
34
|
*/
|
|
31
35
|
readonly desktop: DesktopDriver;
|
|
36
|
+
/** Native terminal workspace state and pane actions in trusted dev/test hosts. */
|
|
37
|
+
readonly terminal: TerminalDriver;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ========================== terminal tier ==========================
|
|
41
|
+
|
|
42
|
+
export type TerminalSplitDirection = 'left' | 'right' | 'up' | 'down';
|
|
43
|
+
|
|
44
|
+
export interface TerminalSurfaceRef {
|
|
45
|
+
/** Stable id returned by `lx.shell.openDeclared('terminal', { key })`. */
|
|
46
|
+
surface: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface TerminalPaneSnapshot {
|
|
50
|
+
paneId: string;
|
|
51
|
+
active: boolean;
|
|
52
|
+
visible: boolean;
|
|
53
|
+
frame: { x: number; y: number; width: number; height: number };
|
|
54
|
+
grid: {
|
|
55
|
+
cols: number;
|
|
56
|
+
rows: number;
|
|
57
|
+
generation: number;
|
|
58
|
+
imageGeneration: number;
|
|
59
|
+
imageCount: number;
|
|
60
|
+
imagePlacementCount: number;
|
|
61
|
+
defaultForeground: number;
|
|
62
|
+
defaultBackground: number;
|
|
63
|
+
cursorRow: number;
|
|
64
|
+
cursorCol: number;
|
|
65
|
+
cursorVisible: boolean;
|
|
66
|
+
cursorStyle: 'block' | 'bar' | 'underline' | 'block-hollow';
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type TerminalPaneTree =
|
|
71
|
+
| { kind: 'leaf'; pane: TerminalPaneSnapshot }
|
|
72
|
+
| {
|
|
73
|
+
kind: 'split';
|
|
74
|
+
/** `horizontal` places children left/right; `vertical` stacks them. */
|
|
75
|
+
axis: 'horizontal' | 'vertical';
|
|
76
|
+
children: TerminalPaneTree[];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export interface TerminalTabSnapshot {
|
|
80
|
+
id: string;
|
|
81
|
+
active: boolean;
|
|
82
|
+
activePaneId?: string;
|
|
83
|
+
paneCount: number;
|
|
84
|
+
tree?: TerminalPaneTree;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Semantic state published by the native terminal host after layout. */
|
|
88
|
+
export interface TerminalWorkspaceSnapshot {
|
|
89
|
+
surfaceId: string;
|
|
90
|
+
presentation: 'main' | 'aside';
|
|
91
|
+
visible: boolean;
|
|
92
|
+
/** Expanded to the full content area rather than its docked size. */
|
|
93
|
+
maximized: boolean;
|
|
94
|
+
activeTabId?: string;
|
|
95
|
+
tabCount: number;
|
|
96
|
+
paneCount: number;
|
|
97
|
+
configGeneration: number;
|
|
98
|
+
visualGeneration: number;
|
|
99
|
+
config: TerminalSettingsValue;
|
|
100
|
+
chrome: {
|
|
101
|
+
surface: string;
|
|
102
|
+
header: string;
|
|
103
|
+
separator: string;
|
|
104
|
+
text: string;
|
|
105
|
+
textMuted: string;
|
|
106
|
+
cursor: string;
|
|
107
|
+
selectionBackground: string;
|
|
108
|
+
selectionForeground: string;
|
|
109
|
+
};
|
|
110
|
+
tabs: TerminalTabSnapshot[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface TerminalSplitOptions extends TerminalSurfaceRef {
|
|
114
|
+
direction: TerminalSplitDirection;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Native terminal automation; available only to trusted dev/test hosts. */
|
|
118
|
+
export interface TerminalDriver {
|
|
119
|
+
snapshot(options: TerminalSurfaceRef): Promise<TerminalWorkspaceSnapshot>;
|
|
120
|
+
/** Send text to the focused pane, as if typed into its PTY. */
|
|
121
|
+
input(options: TerminalInputOptions): Promise<TerminalWorkspaceSnapshot>;
|
|
122
|
+
split(options: TerminalSplitOptions): Promise<TerminalWorkspaceSnapshot>;
|
|
123
|
+
/** Open a tab and activate it. Resolves with the snapshot that follows. */
|
|
124
|
+
newTab(options: TerminalSurfaceRef): Promise<TerminalWorkspaceSnapshot>;
|
|
125
|
+
/** Expand to the full content area, or return to the docked size. */
|
|
126
|
+
setMaximized(options: TerminalMaximizeOptions): Promise<TerminalWorkspaceSnapshot>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface TerminalInputOptions extends TerminalSurfaceRef {
|
|
130
|
+
text: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface TerminalMaximizeOptions extends TerminalSurfaceRef {
|
|
134
|
+
maximized: boolean;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ============================ shell tier ============================
|
|
138
|
+
|
|
139
|
+
/** One ordered shortcut in the host shell's persisted Pin collection. */
|
|
140
|
+
export type AutomationShellPin =
|
|
141
|
+
| {
|
|
142
|
+
/** A host workspace shortcut; activation opens/focuses the app as main. */
|
|
143
|
+
kind: 'lxapp';
|
|
144
|
+
/** Installed lxapp id. This is not a page name or route. */
|
|
145
|
+
key: string;
|
|
146
|
+
}
|
|
147
|
+
| {
|
|
148
|
+
/** A website shortcut opened/focused as a main browser tab. */
|
|
149
|
+
kind: 'bookmark';
|
|
150
|
+
/** Persisted bookmark id. */
|
|
151
|
+
key: string;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export type SetAutomationShellPinOptions = AutomationShellPin & {
|
|
155
|
+
pinned: boolean;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Host-shell state for test setup and end-to-end assertions. This does not
|
|
160
|
+
* customize an lxapp's production shell; use `lx.shell` for app behavior.
|
|
161
|
+
*/
|
|
162
|
+
export interface ShellDriver {
|
|
163
|
+
/** Ordered shortcuts exactly as projected into the host sidebar. */
|
|
164
|
+
pins(): Promise<AutomationShellPin[]>;
|
|
165
|
+
/**
|
|
166
|
+
* Idempotently persist or remove one shortcut. New Pins append to the
|
|
167
|
+
* existing order; adding beyond the host limit rejects without mutation.
|
|
168
|
+
* Returns the resulting complete order.
|
|
169
|
+
*/
|
|
170
|
+
setPin(options: SetAutomationShellPinOptions): Promise<AutomationShellPin[]>;
|
|
32
171
|
}
|
|
33
172
|
|
|
34
173
|
// ============================ page tier ============================
|
|
@@ -89,7 +228,17 @@ export interface PageScrollToOptions extends PageTarget {
|
|
|
89
228
|
css: string;
|
|
90
229
|
}
|
|
91
230
|
|
|
92
|
-
export type PageWaitState =
|
|
231
|
+
export type PageWaitState =
|
|
232
|
+
| 'attached'
|
|
233
|
+
| 'detached'
|
|
234
|
+
| 'visible'
|
|
235
|
+
| 'hidden'
|
|
236
|
+
| 'enabled'
|
|
237
|
+
| 'editable'
|
|
238
|
+
/** @deprecated Use `attached`. */
|
|
239
|
+
| 'exists'
|
|
240
|
+
/** @deprecated Use `detached`. */
|
|
241
|
+
| 'gone';
|
|
93
242
|
|
|
94
243
|
export interface PageWaitForOptions extends PageTarget {
|
|
95
244
|
css: string;
|
|
@@ -99,7 +248,12 @@ export interface PageWaitForOptions extends PageTarget {
|
|
|
99
248
|
timeoutMs?: number;
|
|
100
249
|
}
|
|
101
250
|
|
|
102
|
-
/**
|
|
251
|
+
/**
|
|
252
|
+
* An element's viewport rectangle (viewport-relative CSS pixels).
|
|
253
|
+
* Windows LingXia WebViews use a 1:1 CSS-to-child-window rasterization scale,
|
|
254
|
+
* so combine this with that WebView's desktop bounds without multiplying by
|
|
255
|
+
* `DesktopWindowInfo.scale`.
|
|
256
|
+
*/
|
|
103
257
|
export interface ElementRect {
|
|
104
258
|
left: number;
|
|
105
259
|
top: number;
|
|
@@ -257,6 +411,103 @@ export interface LxAppEvalOptions {
|
|
|
257
411
|
timeoutMs?: number;
|
|
258
412
|
}
|
|
259
413
|
|
|
414
|
+
export type SurfaceLayoutSizeClass = 'compact' | 'medium' | 'expanded';
|
|
415
|
+
export type SurfaceLayoutSwitcherForm = 'none' | 'sidebar' | 'rail';
|
|
416
|
+
export type SurfaceLayoutSplitForm = 'none' | 'split' | 'collapsible' | 'fullScreen';
|
|
417
|
+
export type SurfaceLayoutEdge = 'left' | 'right' | 'top' | 'bottom';
|
|
418
|
+
|
|
419
|
+
export type SurfaceLayoutIcon =
|
|
420
|
+
| { source: 'builtIn'; name: string }
|
|
421
|
+
| { source: 'resource'; uri: string }
|
|
422
|
+
| { source: 'providerAsset'; provider: string; key: string };
|
|
423
|
+
|
|
424
|
+
/** Resolved content identity carried by one host switcher item. */
|
|
425
|
+
export type SurfaceSwitcherContent =
|
|
426
|
+
| { kind: 'lxapp'; appId: string }
|
|
427
|
+
| { kind: 'page'; appId: string }
|
|
428
|
+
| { kind: 'browser' }
|
|
429
|
+
| { kind: 'native'; capability: string };
|
|
430
|
+
|
|
431
|
+
export interface SurfaceSwitcherItem {
|
|
432
|
+
surfaceId: string;
|
|
433
|
+
content: SurfaceSwitcherContent;
|
|
434
|
+
title?: string;
|
|
435
|
+
icon?: SurfaceLayoutIcon;
|
|
436
|
+
active: boolean;
|
|
437
|
+
root: boolean;
|
|
438
|
+
closable: boolean;
|
|
439
|
+
renameable: boolean;
|
|
440
|
+
titleOverridden: boolean;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/** Ordered semantic model behind the host's main-surface switcher. */
|
|
444
|
+
export interface SurfaceSwitcherSnapshot {
|
|
445
|
+
/** Monotonically changes when the host surface model changes. */
|
|
446
|
+
revision: number;
|
|
447
|
+
rootSurfaceId?: string;
|
|
448
|
+
activeSurfaceId?: string;
|
|
449
|
+
items: SurfaceSwitcherItem[];
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export interface SurfaceLayoutAside {
|
|
453
|
+
id: string;
|
|
454
|
+
edge?: SurfaceLayoutEdge;
|
|
455
|
+
preferredSize?: number;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface SurfaceLayoutAsideSlot {
|
|
459
|
+
kind: 'lxapp' | 'browser' | 'native';
|
|
460
|
+
edge?: SurfaceLayoutEdge;
|
|
461
|
+
/** Stable tab order within this content-kind region. */
|
|
462
|
+
children: string[];
|
|
463
|
+
activeChild?: string;
|
|
464
|
+
visible: boolean;
|
|
465
|
+
overlay: boolean;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export type SurfaceLayoutFloatAnchor =
|
|
469
|
+
| { to: 'screen' }
|
|
470
|
+
| { to: 'surface'; surfaceId: string };
|
|
471
|
+
|
|
472
|
+
export interface SurfaceLayoutFloat {
|
|
473
|
+
id: string;
|
|
474
|
+
anchor: SurfaceLayoutFloatAnchor;
|
|
475
|
+
dismiss: 'tapOutside' | 'manual';
|
|
476
|
+
modal: boolean;
|
|
477
|
+
closeButton: boolean;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** Id-only surface tree emitted by the shared layout core. */
|
|
481
|
+
export type SurfaceLayoutTree =
|
|
482
|
+
| { kind: 'leaf'; surfaceId: string }
|
|
483
|
+
| {
|
|
484
|
+
kind: 'split';
|
|
485
|
+
axis: 'horizontal' | 'vertical';
|
|
486
|
+
children: SurfaceLayoutTree[];
|
|
487
|
+
weights: number[];
|
|
488
|
+
}
|
|
489
|
+
| { kind: 'tabs'; activeId: string; children: string[] }
|
|
490
|
+
| { kind: 'freeform'; surfaceId: string };
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Read-only automation snapshot of the exact render plan consumed by the host
|
|
494
|
+
* skin. Use this for end-to-end assertions; production lxapp behavior should
|
|
495
|
+
* depend on `SurfaceHandle`, not host layout internals.
|
|
496
|
+
*/
|
|
497
|
+
export interface SurfaceLayoutSnapshot {
|
|
498
|
+
sizeClass: SurfaceLayoutSizeClass;
|
|
499
|
+
bottomOwner: 'app';
|
|
500
|
+
switcherForm: SurfaceLayoutSwitcherForm;
|
|
501
|
+
splitForm: SurfaceLayoutSplitForm;
|
|
502
|
+
mains: string[];
|
|
503
|
+
activeMainId?: string;
|
|
504
|
+
mainSwitcher: SurfaceSwitcherSnapshot;
|
|
505
|
+
asides: SurfaceLayoutAside[];
|
|
506
|
+
asideSlots: SurfaceLayoutAsideSlot[];
|
|
507
|
+
floats: SurfaceLayoutFloat[];
|
|
508
|
+
tree?: SurfaceLayoutTree;
|
|
509
|
+
}
|
|
510
|
+
|
|
260
511
|
/** Capability for one selected running lxapp. */
|
|
261
512
|
export interface LxAppDriver {
|
|
262
513
|
readonly page: PageDriver;
|
|
@@ -265,6 +516,8 @@ export interface LxAppDriver {
|
|
|
265
516
|
info(): Promise<LxAppRuntimeInfo>;
|
|
266
517
|
/** Configured pages of the selected lxapp. */
|
|
267
518
|
pages(): Promise<LxAppPageConfig[]>;
|
|
519
|
+
/** Authoritative host surface render plan, for end-to-end assertions. */
|
|
520
|
+
surfaceLayout(): Promise<SurfaceLayoutSnapshot>;
|
|
268
521
|
/** Logic-runtime eval; self-eval from that Logic runtime is rejected. */
|
|
269
522
|
eval(options: LxAppEvalOptions): Promise<unknown>;
|
|
270
523
|
}
|
|
@@ -291,11 +544,46 @@ export interface LxAppRuntimeInfo {
|
|
|
291
544
|
pages_count: number;
|
|
292
545
|
page_entries: LxAppPageEntry[];
|
|
293
546
|
page_stack: string[];
|
|
547
|
+
tab_bar: LxAppRuntimeTabBarInfo | null;
|
|
548
|
+
navigation_bar: LxAppRuntimeNavigationBarInfo | null;
|
|
294
549
|
lxapp_dir: string;
|
|
295
550
|
data_dir: string;
|
|
296
551
|
cache_dir: string;
|
|
297
552
|
}
|
|
298
553
|
|
|
554
|
+
/** Runtime NavigationBar state exposed for deterministic host-level assertions. */
|
|
555
|
+
export interface LxAppRuntimeNavigationBarInfo {
|
|
556
|
+
title: string;
|
|
557
|
+
home_button: 'auto' | 'hidden';
|
|
558
|
+
home_button_visible: boolean;
|
|
559
|
+
runtime_style: {
|
|
560
|
+
background_color: string | null;
|
|
561
|
+
foreground_color: string | null;
|
|
562
|
+
divider_color: string | null;
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/** Runtime TabBar state exposed for deterministic host-level assertions. */
|
|
567
|
+
export interface LxAppRuntimeTabBarInfo {
|
|
568
|
+
presentation: 'standard' | 'immersive';
|
|
569
|
+
visibility: 'auto' | 'visible' | 'hidden';
|
|
570
|
+
route_visible: boolean;
|
|
571
|
+
effective_visible: boolean;
|
|
572
|
+
selected_index: number;
|
|
573
|
+
runtime_style: {
|
|
574
|
+
foreground_color: string | null;
|
|
575
|
+
selected_foreground_color: string | null;
|
|
576
|
+
};
|
|
577
|
+
items: Array<{
|
|
578
|
+
index: number;
|
|
579
|
+
text: string | null;
|
|
580
|
+
icon_path: string | null;
|
|
581
|
+
selected_icon_path: string | null;
|
|
582
|
+
badge: string | null;
|
|
583
|
+
red_dot: boolean;
|
|
584
|
+
}>;
|
|
585
|
+
}
|
|
586
|
+
|
|
299
587
|
/** Selects a running lxapp by id; defaults to the current app. */
|
|
300
588
|
export interface LxAppRef {
|
|
301
589
|
/** LxApp id, or `"current"` (default). */
|
|
@@ -371,7 +659,7 @@ export interface DeviceSetOptions {
|
|
|
371
659
|
}
|
|
372
660
|
|
|
373
661
|
/**
|
|
374
|
-
* Simulated-device control (`lxdev
|
|
662
|
+
* Simulated-device control (`lxdev runner`). Only functional in a host
|
|
375
663
|
* runner that registered a device controller; otherwise every call rejects.
|
|
376
664
|
*/
|
|
377
665
|
export interface DeviceDriver {
|
|
@@ -676,6 +964,10 @@ export interface DesktopWindowInfo {
|
|
|
676
964
|
pid: number;
|
|
677
965
|
bounds: DesktopRect;
|
|
678
966
|
display_id: string;
|
|
967
|
+
/**
|
|
968
|
+
* Display DIP-to-physical scale. `bounds` are already backend-native; do not
|
|
969
|
+
* multiply them by this value.
|
|
970
|
+
*/
|
|
679
971
|
scale: number;
|
|
680
972
|
dpi: number;
|
|
681
973
|
visible: boolean;
|
|
@@ -861,11 +1153,15 @@ export interface DesktopKeyTypeOptions extends DesktopInputTarget {
|
|
|
861
1153
|
}
|
|
862
1154
|
|
|
863
1155
|
export interface DesktopKeyPressOptions extends DesktopInputTarget {
|
|
1156
|
+
/** Case-insensitive named key (`Enter`, `ArrowDown`, `Down`, etc.) or one
|
|
1157
|
+
* printable character. */
|
|
864
1158
|
key: string;
|
|
865
1159
|
modifiers?: KeyModifier[];
|
|
866
1160
|
}
|
|
867
1161
|
|
|
868
1162
|
export interface DesktopKeyNameOptions extends DesktopInputTarget {
|
|
1163
|
+
/** Case-insensitive named key (`Enter`, `ArrowDown`, `Down`, etc.) or one
|
|
1164
|
+
* printable character. */
|
|
869
1165
|
key: string;
|
|
870
1166
|
}
|
|
871
1167
|
|
package/src/error.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SurfaceErrorCode } from './generated/logic.js';
|
|
1
2
|
import { ERR_CODE_INFO_BY_CODE, type LxErrorCodeInfo } from "./generated/error";
|
|
2
3
|
|
|
3
4
|
const ERR_CODE_INDEX = ERR_CODE_INFO_BY_CODE as Record<number, LxErrorCodeInfo>;
|
|
@@ -9,11 +10,27 @@ export interface LxApiError {
|
|
|
9
10
|
readonly raw: unknown;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
/** Check an already-normalized error without modifying the caught value. */
|
|
12
14
|
export function isLxApiError(error: unknown): error is LxApiError {
|
|
13
|
-
|
|
15
|
+
const target = toRecord(error);
|
|
16
|
+
if (!target) return false;
|
|
17
|
+
const code = parseIntegerCode(target.code);
|
|
18
|
+
if (code === null) return false;
|
|
19
|
+
const info = infoForLxErrorCode(code);
|
|
20
|
+
return Boolean(
|
|
21
|
+
info &&
|
|
22
|
+
target.code === code &&
|
|
23
|
+
target.key === info.key &&
|
|
24
|
+
typeof target.message === "string" &&
|
|
25
|
+
Object.prototype.hasOwnProperty.call(target, "raw"),
|
|
26
|
+
);
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
function readMessage(error: unknown): string {
|
|
30
|
+
const root = toRecord(error);
|
|
31
|
+
const data = root && toRecord(root.data);
|
|
32
|
+
const detail = data?.detail;
|
|
33
|
+
if (typeof detail === "string" && detail.trim() !== "") return detail;
|
|
17
34
|
if (typeof error === "string") return error;
|
|
18
35
|
if (error instanceof Error && typeof error.message === "string") return error.message;
|
|
19
36
|
if (typeof error === "object" && error !== null) {
|
|
@@ -50,6 +67,35 @@ export function extractLxErrorCode(error: unknown): number | null {
|
|
|
50
67
|
return parseIntegerCode(data.bizCode) ?? parseIntegerCode(data.code);
|
|
51
68
|
}
|
|
52
69
|
|
|
70
|
+
/**
|
|
71
|
+
* The surface code carried by a `lx.surface.*` / `lx.shell.*` rejection.
|
|
72
|
+
*
|
|
73
|
+
* A rejection's `code` is the transport-level host code shared with every
|
|
74
|
+
* other `lx` API; the surface-specific member of `SurfaceErrorCode` rides on
|
|
75
|
+
* `data.code`. Reading it through this helper keeps callers off both the
|
|
76
|
+
* message text and the shape.
|
|
77
|
+
*/
|
|
78
|
+
export function surfaceErrorCode(error: unknown): SurfaceErrorCode | null {
|
|
79
|
+
const root = toRecord(error);
|
|
80
|
+
const data = root ? toRecord(root.data) : null;
|
|
81
|
+
const code = data?.code;
|
|
82
|
+
return typeof code === 'string' && SURFACE_ERROR_CODES.includes(code as SurfaceErrorCode)
|
|
83
|
+
? (code as SurfaceErrorCode)
|
|
84
|
+
: null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Every member of `SurfaceErrorCode`, for runtime narrowing. */
|
|
88
|
+
export const SURFACE_ERROR_CODES = [
|
|
89
|
+
'unsupported_placement',
|
|
90
|
+
'denied',
|
|
91
|
+
'not_declared',
|
|
92
|
+
'invalid_arg',
|
|
93
|
+
'already_open_other_role',
|
|
94
|
+
'closed',
|
|
95
|
+
'capability_missing',
|
|
96
|
+
'failed',
|
|
97
|
+
] as const satisfies readonly SurfaceErrorCode[];
|
|
98
|
+
|
|
53
99
|
export function isKnownLxErrorCode(code: number): boolean {
|
|
54
100
|
return Number.isInteger(code) && Object.prototype.hasOwnProperty.call(ERR_CODE_INDEX, code);
|
|
55
101
|
}
|
package/src/generated/i18n.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const I18N_KEYS = [
|
|
|
27
27
|
"browser_page_menu",
|
|
28
28
|
"browser_pin_to_sidebar",
|
|
29
29
|
"browser_remove_bookmark",
|
|
30
|
+
"browser_tabs",
|
|
30
31
|
"browser_unpin",
|
|
31
32
|
"camera_access_denied",
|
|
32
33
|
"camera_audio_init_failed",
|
|
@@ -57,6 +58,7 @@ export const I18N_KEYS = [
|
|
|
57
58
|
"common_delete",
|
|
58
59
|
"common_done",
|
|
59
60
|
"common_exit",
|
|
61
|
+
"common_forward",
|
|
60
62
|
"common_loading",
|
|
61
63
|
"common_ok",
|
|
62
64
|
"common_refresh",
|
|
@@ -132,6 +134,11 @@ export const I18N_KEYS = [
|
|
|
132
134
|
"permission_wifi_reason",
|
|
133
135
|
"shell_pin_limit_message",
|
|
134
136
|
"shell_pin_limit_title",
|
|
137
|
+
"surface_close",
|
|
138
|
+
"surface_close_after",
|
|
139
|
+
"surface_close_others",
|
|
140
|
+
"surface_rename",
|
|
141
|
+
"surface_reset_title",
|
|
135
142
|
"terminal_change_title",
|
|
136
143
|
"terminal_close_pane",
|
|
137
144
|
"terminal_copy",
|
|
@@ -139,6 +146,7 @@ export const I18N_KEYS = [
|
|
|
139
146
|
"terminal_paste",
|
|
140
147
|
"terminal_read_only",
|
|
141
148
|
"terminal_reset",
|
|
149
|
+
"terminal_search",
|
|
142
150
|
"terminal_split_down",
|
|
143
151
|
"terminal_split_left",
|
|
144
152
|
"terminal_split_right",
|