@stacksjs/desktop 0.2.21 → 0.2.25
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/_bridge.d.ts +105 -0
- package/dist/app-info.d.ts +22 -0
- package/dist/apple-script.d.ts +8 -0
- package/dist/audio.d.ts +17 -0
- package/dist/battery.d.ts +15 -0
- package/dist/biometric.d.ts +14 -0
- package/dist/bluetooth.d.ts +52 -0
- package/dist/bonjour.d.ts +13 -0
- package/dist/capabilities.d.ts +31 -0
- package/dist/clipboard.d.ts +11 -0
- package/dist/continuity-camera.d.ts +10 -0
- package/dist/coreml.d.ts +6 -0
- package/dist/crash-reporter.d.ts +46 -0
- package/dist/deep-link.d.ts +10 -0
- package/dist/drag-out.d.ts +18 -0
- package/dist/file-associations.d.ts +5 -0
- package/dist/fs.d.ts +62 -0
- package/dist/global-shortcuts.d.ts +19 -0
- package/dist/handoff.d.ts +24 -0
- package/dist/hotkeys.d.ts +10 -8
- package/dist/iap.d.ts +79 -0
- package/dist/index.d.ts +322 -0
- package/dist/index.js +2505 -20
- package/dist/index.js.map +55 -7
- package/dist/keychain.d.ts +7 -0
- package/dist/live-activities.d.ts +11 -0
- package/dist/local-server.d.ts +23 -0
- package/dist/location.d.ts +29 -0
- package/dist/log.d.ts +7 -0
- package/dist/menu.d.ts +29 -0
- package/dist/midi.d.ts +17 -0
- package/dist/native-autolaunch.d.ts +6 -0
- package/dist/network.d.ts +33 -0
- package/dist/notifications.d.ts +56 -0
- package/dist/pdf.d.ts +5 -0
- package/dist/permissions.d.ts +21 -0
- package/dist/printing.d.ts +9 -0
- package/dist/screen-capture.d.ts +11 -0
- package/dist/screen.d.ts +18 -0
- package/dist/serial.d.ts +15 -0
- package/dist/service-menu.d.ts +10 -0
- package/dist/shell.d.ts +28 -0
- package/dist/speech-recognition.d.ts +12 -0
- package/dist/speech.d.ts +21 -0
- package/dist/spotlight.d.ts +12 -0
- package/dist/system.d.ts +16 -0
- package/dist/tags.d.ts +6 -0
- package/dist/test-utils.d.ts +17 -0
- package/dist/test-utils.js +108 -0
- package/dist/test-utils.js.map +10 -0
- package/dist/theme.d.ts +10 -0
- package/dist/touchbar.d.ts +29 -0
- package/dist/updater.d.ts +37 -0
- package/dist/vision.d.ts +17 -0
- package/dist/window-events.d.ts +20 -0
- package/package.json +5 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const keychain: KeychainAPI;
|
|
2
|
+
export declare interface KeychainAPI {
|
|
3
|
+
set: (service: string, account: string, password: string) => Promise<void>
|
|
4
|
+
get: (service: string, account: string) => Promise<string | null>
|
|
5
|
+
delete: (service: string, account: string) => Promise<void>
|
|
6
|
+
has: (service: string, account: string) => Promise<boolean>
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const liveActivities: LiveActivitiesAPI;
|
|
2
|
+
export declare interface LiveActivityState {
|
|
3
|
+
title?: string
|
|
4
|
+
webpageURL?: string
|
|
5
|
+
state?: Record<string, unknown>
|
|
6
|
+
}
|
|
7
|
+
export declare interface LiveActivitiesAPI {
|
|
8
|
+
start: (type: string, state?: LiveActivityState) => Promise<boolean>
|
|
9
|
+
update: (state: LiveActivityState) => Promise<boolean>
|
|
10
|
+
stop: () => Promise<void>
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const localServer: LocalServerAPI;
|
|
2
|
+
export declare interface LocalServerStartResult {
|
|
3
|
+
port: number
|
|
4
|
+
started: boolean
|
|
5
|
+
alreadyRunning?: boolean
|
|
6
|
+
reason?: string
|
|
7
|
+
}
|
|
8
|
+
export declare interface LocalServerRequestEvent {
|
|
9
|
+
method: string
|
|
10
|
+
url: string
|
|
11
|
+
}
|
|
12
|
+
export declare interface LocalServerRespondOptions {
|
|
13
|
+
status?: number
|
|
14
|
+
body?: string
|
|
15
|
+
contentType?: string
|
|
16
|
+
}
|
|
17
|
+
export declare interface LocalServerAPI {
|
|
18
|
+
start: (port?: number, host?: string) => Promise<LocalServerStartResult>
|
|
19
|
+
stop: () => Promise<void>
|
|
20
|
+
respond: (options?: LocalServerRespondOptions) => Promise<void>
|
|
21
|
+
onRequest: (cb: (event: LocalServerRequestEvent) => void) => () => void
|
|
22
|
+
awaitOAuthCallback: (options?: { port?: number, host?: string, timeoutMs?: number, successHTML?: string }) => Promise<{ url: string, port: number }>
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const location: LocationAPI;
|
|
2
|
+
export declare interface LocationCoordinate {
|
|
3
|
+
latitude: number
|
|
4
|
+
longitude: number
|
|
5
|
+
altitude?: number
|
|
6
|
+
horizontalAccuracy?: number
|
|
7
|
+
verticalAccuracy?: number
|
|
8
|
+
speed?: number
|
|
9
|
+
}
|
|
10
|
+
export declare interface LocationWatchOptions {
|
|
11
|
+
mode?: 'continuous' | 'significant'
|
|
12
|
+
distanceFilter?: number
|
|
13
|
+
}
|
|
14
|
+
export declare interface LocationAPI {
|
|
15
|
+
requestPermission: (mode?: 'whenInUse' | 'always') => Promise<LocationAuthStatus>
|
|
16
|
+
getAuthorization: () => Promise<LocationAuthStatus>
|
|
17
|
+
getCurrentLocation: () => Promise<{ requested: boolean }>
|
|
18
|
+
startWatching: (options?: LocationWatchOptions) => Promise<boolean>
|
|
19
|
+
stopWatching: () => Promise<void>
|
|
20
|
+
onUpdate: (cb: (loc: LocationCoordinate) => void) => () => void
|
|
21
|
+
onError: (cb: (err: { message: string }) => void) => () => void
|
|
22
|
+
onAuthChanged: (cb: (info: { status: LocationAuthStatus }) => void) => () => void
|
|
23
|
+
}
|
|
24
|
+
export type LocationAuthStatus = | 'undetermined'
|
|
25
|
+
| 'restricted-or-denied'
|
|
26
|
+
| 'authorizedAlways'
|
|
27
|
+
| 'authorizedWhenInUse'
|
|
28
|
+
| 'not-supported'
|
|
29
|
+
| 'unknown';
|
package/dist/log.d.ts
ADDED
package/dist/menu.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const menu: MenuAPI;
|
|
2
|
+
export declare interface MenuItem {
|
|
3
|
+
id: string
|
|
4
|
+
label?: string
|
|
5
|
+
role?: string
|
|
6
|
+
accelerator?: string
|
|
7
|
+
separator?: boolean
|
|
8
|
+
checkable?: boolean
|
|
9
|
+
checked?: boolean
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
submenu?: MenuItem[]
|
|
12
|
+
icon?: string
|
|
13
|
+
}
|
|
14
|
+
export declare interface MenuActionEvent {
|
|
15
|
+
id: string
|
|
16
|
+
}
|
|
17
|
+
export declare interface MenuAPI {
|
|
18
|
+
set: (items: MenuItem[]) => Promise<void>
|
|
19
|
+
setDock: (items: MenuItem[]) => Promise<void>
|
|
20
|
+
addItem: (parent: string, item: MenuItem) => Promise<void>
|
|
21
|
+
removeItem: (id: string) => Promise<void>
|
|
22
|
+
enableItem: (id: string) => Promise<void>
|
|
23
|
+
disableItem: (id: string) => Promise<void>
|
|
24
|
+
checkItem: (id: string) => Promise<void>
|
|
25
|
+
uncheckItem: (id: string) => Promise<void>
|
|
26
|
+
setItemLabel: (id: string, label: string) => Promise<void>
|
|
27
|
+
clearDock: () => Promise<void>
|
|
28
|
+
onAction: (cb: (event: MenuActionEvent) => void) => () => void
|
|
29
|
+
}
|
package/dist/midi.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const midi: MIDIAPI;
|
|
2
|
+
export declare interface MIDIEndpoint {
|
|
3
|
+
index: number
|
|
4
|
+
name: string
|
|
5
|
+
}
|
|
6
|
+
export declare interface MIDIMessageEvent {
|
|
7
|
+
index: number
|
|
8
|
+
data: number[]
|
|
9
|
+
}
|
|
10
|
+
export declare interface MIDIAPI {
|
|
11
|
+
listSources: () => Promise<MIDIEndpoint[]>
|
|
12
|
+
listDestinations: () => Promise<MIDIEndpoint[]>
|
|
13
|
+
send: (destinationIndex: number, data: Uint8Array | number[]) => Promise<{ ok: boolean, reason?: string }>
|
|
14
|
+
subscribe: (sourceIndex: number) => Promise<{ ok: boolean, reason?: string }>
|
|
15
|
+
unsubscribe: (sourceIndex: number) => Promise<{ ok: boolean }>
|
|
16
|
+
onMessage: (cb: (event: MIDIMessageEvent) => void) => () => void
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const network: NetworkAPI;
|
|
2
|
+
export declare interface NetworkInterface {
|
|
3
|
+
name: string
|
|
4
|
+
address: string
|
|
5
|
+
isUp: boolean
|
|
6
|
+
isLoopback: boolean
|
|
7
|
+
}
|
|
8
|
+
export declare interface ProxySettings {
|
|
9
|
+
http?: string
|
|
10
|
+
https?: string
|
|
11
|
+
ftp?: string
|
|
12
|
+
socks?: string
|
|
13
|
+
exceptions?: string[]
|
|
14
|
+
}
|
|
15
|
+
export declare interface NetworkAPI {
|
|
16
|
+
connectionType: () => Promise<ConnectionType>
|
|
17
|
+
wifiSSID: () => Promise<string | undefined>
|
|
18
|
+
wifiSignalStrength: () => Promise<number | undefined>
|
|
19
|
+
ipAddress: () => Promise<string>
|
|
20
|
+
macAddress: () => Promise<string>
|
|
21
|
+
interfaces: () => Promise<NetworkInterface[]>
|
|
22
|
+
isVPNConnected: () => Promise<boolean>
|
|
23
|
+
proxySettings: () => Promise<ProxySettings>
|
|
24
|
+
openPreferences: () => Promise<void>
|
|
25
|
+
onChange: (cb: (info: { type: ConnectionType, online: boolean }) => void) => () => void
|
|
26
|
+
}
|
|
27
|
+
export type ConnectionType = | 'wifi'
|
|
28
|
+
| 'ethernet'
|
|
29
|
+
| 'cellular'
|
|
30
|
+
| 'bluetooth'
|
|
31
|
+
| 'vpn'
|
|
32
|
+
| 'none'
|
|
33
|
+
| 'unknown';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export declare const notifications: SystemNotifications;
|
|
2
|
+
export declare interface NotificationAttachment {
|
|
3
|
+
id?: string
|
|
4
|
+
url: string
|
|
5
|
+
type?: 'image' | 'audio' | 'video' | string
|
|
6
|
+
}
|
|
7
|
+
export declare interface NotificationAction {
|
|
8
|
+
id: string
|
|
9
|
+
title: string
|
|
10
|
+
style?: 'default' | 'destructive' | 'foreground'
|
|
11
|
+
authenticationRequired?: boolean
|
|
12
|
+
}
|
|
13
|
+
export declare interface NotificationOptions {
|
|
14
|
+
title: string
|
|
15
|
+
body?: string
|
|
16
|
+
subtitle?: string
|
|
17
|
+
id?: string
|
|
18
|
+
triggerAt?: string | number | Date
|
|
19
|
+
sound?: 'default' | 'silent' | string
|
|
20
|
+
icon?: string
|
|
21
|
+
badge?: number
|
|
22
|
+
data?: unknown
|
|
23
|
+
attachments?: NotificationAttachment[]
|
|
24
|
+
actions?: NotificationAction[]
|
|
25
|
+
reply?: {
|
|
26
|
+
placeholder?: string
|
|
27
|
+
sendButtonTitle?: string
|
|
28
|
+
}
|
|
29
|
+
categoryId?: string
|
|
30
|
+
threadId?: string
|
|
31
|
+
}
|
|
32
|
+
export declare interface NotificationActionEvent {
|
|
33
|
+
notificationId?: string
|
|
34
|
+
actionId: string
|
|
35
|
+
isDefault?: boolean
|
|
36
|
+
}
|
|
37
|
+
export declare interface NotificationReplyEvent {
|
|
38
|
+
notificationId?: string
|
|
39
|
+
text: string
|
|
40
|
+
}
|
|
41
|
+
export declare interface NotificationCategory {
|
|
42
|
+
id: string
|
|
43
|
+
actions: NotificationAction[]
|
|
44
|
+
}
|
|
45
|
+
export declare interface SystemNotifications {
|
|
46
|
+
show: (options: NotificationOptions) => Promise<void>
|
|
47
|
+
schedule: (options: NotificationOptions) => Promise<void>
|
|
48
|
+
cancel: (id: string) => Promise<void>
|
|
49
|
+
cancelAll: () => Promise<void>
|
|
50
|
+
setBadge: (n: number) => Promise<void>
|
|
51
|
+
clearBadge: () => Promise<void>
|
|
52
|
+
requestPermission: () => Promise<boolean>
|
|
53
|
+
registerCategories: (categories: NotificationCategory[]) => Promise<void>
|
|
54
|
+
onActionClicked: (cb: (event: NotificationActionEvent) => void) => () => void
|
|
55
|
+
onReply: (cb: (event: NotificationReplyEvent) => void) => () => void
|
|
56
|
+
}
|
package/dist/pdf.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const permissions: PermissionsAPI;
|
|
2
|
+
export declare interface PermissionsAPI {
|
|
3
|
+
check: (name: PermissionName) => Promise<PermissionStatus>
|
|
4
|
+
request: (name: PermissionName) => Promise<PermissionStatus>
|
|
5
|
+
openSettings: (name?: PermissionName) => Promise<void>
|
|
6
|
+
}
|
|
7
|
+
/** Status values match the macOS TCC convention. */
|
|
8
|
+
export type PermissionStatus = 'granted' | 'denied' | 'restricted' | 'undetermined' | 'not-supported';
|
|
9
|
+
export type PermissionName = | 'camera'
|
|
10
|
+
| 'microphone'
|
|
11
|
+
| 'screen_recording'
|
|
12
|
+
| 'accessibility'
|
|
13
|
+
| 'full_disk_access'
|
|
14
|
+
| 'input_monitoring'
|
|
15
|
+
| 'location'
|
|
16
|
+
| 'notifications'
|
|
17
|
+
| 'contacts'
|
|
18
|
+
| 'calendar'
|
|
19
|
+
| 'reminders'
|
|
20
|
+
| 'photos'
|
|
21
|
+
| 'bluetooth';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const screenCapture: ScreenCaptureAPI;
|
|
2
|
+
export declare interface CapturableWindow {
|
|
3
|
+
id: number
|
|
4
|
+
name: string
|
|
5
|
+
ownerName: string
|
|
6
|
+
}
|
|
7
|
+
export declare interface ScreenCaptureAPI {
|
|
8
|
+
captureScreen: () => Promise<string | null>
|
|
9
|
+
captureWindow: (id: number) => Promise<string | null>
|
|
10
|
+
listWindows: () => Promise<CapturableWindow[]>
|
|
11
|
+
}
|
package/dist/screen.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const screen: ScreenAPI;
|
|
2
|
+
export declare interface Display {
|
|
3
|
+
id: number
|
|
4
|
+
x: number
|
|
5
|
+
y: number
|
|
6
|
+
width: number
|
|
7
|
+
height: number
|
|
8
|
+
workX: number
|
|
9
|
+
workY: number
|
|
10
|
+
workWidth: number
|
|
11
|
+
workHeight: number
|
|
12
|
+
scaleFactor: number
|
|
13
|
+
}
|
|
14
|
+
export declare interface ScreenAPI {
|
|
15
|
+
getDisplays: () => Promise<Display[]>
|
|
16
|
+
getPrimary: () => Promise<Display | null>
|
|
17
|
+
onChange: (cb: () => void) => () => void
|
|
18
|
+
}
|
package/dist/serial.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const serial: SerialAPI;
|
|
2
|
+
export declare interface SerialPort {
|
|
3
|
+
path: string
|
|
4
|
+
}
|
|
5
|
+
export declare interface SerialDataEvent {
|
|
6
|
+
id: string
|
|
7
|
+
data: number[]
|
|
8
|
+
}
|
|
9
|
+
export declare interface SerialAPI {
|
|
10
|
+
list: () => Promise<SerialPort[]>
|
|
11
|
+
open: (path: string, baud?: number) => Promise<{ id?: string, ok: boolean, reason?: string }>
|
|
12
|
+
write: (id: string, data: string) => Promise<{ ok: boolean, reason?: string }>
|
|
13
|
+
close: (id: string) => Promise<void>
|
|
14
|
+
onData: (cb: (event: SerialDataEvent) => void) => () => void
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const serviceMenu: ServiceMenuAPI;
|
|
2
|
+
export declare interface ServiceMenuInvokedEvent {
|
|
3
|
+
name: string
|
|
4
|
+
payload?: { type: string, value: string }
|
|
5
|
+
}
|
|
6
|
+
export declare interface ServiceMenuAPI {
|
|
7
|
+
register: (name: string) => Promise<{ ok: boolean, reason?: string }>
|
|
8
|
+
unregister: (name: string) => Promise<void>
|
|
9
|
+
onInvoked: (cb: (event: ServiceMenuInvokedEvent) => void) => () => void
|
|
10
|
+
}
|
package/dist/shell.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const shell: Shell;
|
|
2
|
+
export declare interface SpawnOptions {
|
|
3
|
+
cwd?: string
|
|
4
|
+
env?: Record<string, string>
|
|
5
|
+
streamOutput?: boolean
|
|
6
|
+
}
|
|
7
|
+
export declare interface Shell {
|
|
8
|
+
openExternal: (url: string) => Promise<void>
|
|
9
|
+
openPath: (path: string) => Promise<void>
|
|
10
|
+
showInFinder: (path: string) => Promise<void>
|
|
11
|
+
spawn: (id: string, command: string, args?: string[], opts?: SpawnOptions) => Promise<void>
|
|
12
|
+
kill: (id: string) => Promise<void>
|
|
13
|
+
getEnv: (name: string) => Promise<string | undefined>
|
|
14
|
+
setEnv: (name: string, value: string) => Promise<void>
|
|
15
|
+
onStdout: (cb: (event: ShellOutputEvent) => void) => () => void
|
|
16
|
+
onStderr: (cb: (event: ShellOutputEvent) => void) => () => void
|
|
17
|
+
onExit: (cb: (event: ShellExitEvent) => void) => () => void
|
|
18
|
+
}
|
|
19
|
+
/** Output chunk from a spawned process. */
|
|
20
|
+
export declare interface ShellOutputEvent {
|
|
21
|
+
id: string
|
|
22
|
+
data: string
|
|
23
|
+
}
|
|
24
|
+
export declare interface ShellExitEvent {
|
|
25
|
+
id: string
|
|
26
|
+
exitCode: number | null
|
|
27
|
+
signal?: string
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const speechRecognition: SpeechRecognitionAPI;
|
|
2
|
+
export declare interface SpeechRecognitionStartOptions {
|
|
3
|
+
language?: string
|
|
4
|
+
partialResults?: boolean
|
|
5
|
+
}
|
|
6
|
+
export declare interface SpeechRecognitionAPI {
|
|
7
|
+
isAvailable: () => Promise<boolean>
|
|
8
|
+
start: (opts?: SpeechRecognitionStartOptions) => Promise<{ started: boolean, reason?: string }>
|
|
9
|
+
stop: () => Promise<void>
|
|
10
|
+
onPartial: (cb: (e: { transcript: string }) => void) => () => void
|
|
11
|
+
onFinal: (cb: (e: { transcript: string }) => void) => () => void
|
|
12
|
+
}
|
package/dist/speech.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const speech: SpeechAPI;
|
|
2
|
+
export declare interface SpeakOptions {
|
|
3
|
+
voice?: string
|
|
4
|
+
rate?: number
|
|
5
|
+
pitch?: number
|
|
6
|
+
volume?: number
|
|
7
|
+
}
|
|
8
|
+
export declare interface SpeechVoice {
|
|
9
|
+
id: string
|
|
10
|
+
name: string
|
|
11
|
+
language: string
|
|
12
|
+
quality: 'default' | 'enhanced'
|
|
13
|
+
}
|
|
14
|
+
export declare interface SpeechAPI {
|
|
15
|
+
speak: (text: string, options?: SpeakOptions) => Promise<void>
|
|
16
|
+
stop: () => Promise<void>
|
|
17
|
+
pause: () => Promise<void>
|
|
18
|
+
resume: () => Promise<void>
|
|
19
|
+
isSpeaking: () => Promise<boolean>
|
|
20
|
+
getVoices: () => Promise<SpeechVoice[]>
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const spotlight: SpotlightAPI;
|
|
2
|
+
export declare interface SpotlightItem {
|
|
3
|
+
id: string
|
|
4
|
+
title: string
|
|
5
|
+
description?: string
|
|
6
|
+
keywords?: string[]
|
|
7
|
+
}
|
|
8
|
+
export declare interface SpotlightAPI {
|
|
9
|
+
index: (items: SpotlightItem[]) => Promise<{ ok: boolean, reason?: string }>
|
|
10
|
+
remove: (ids: string[]) => Promise<{ ok: boolean }>
|
|
11
|
+
removeAll: () => Promise<{ ok: boolean }>
|
|
12
|
+
}
|
package/dist/system.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const system: SystemInfo;
|
|
2
|
+
export declare interface SystemInfo {
|
|
3
|
+
accentColor: () => Promise<string>
|
|
4
|
+
highlightColor: () => Promise<string>
|
|
5
|
+
language: () => Promise<string>
|
|
6
|
+
locale: () => Promise<string>
|
|
7
|
+
timezone: () => Promise<string>
|
|
8
|
+
is24HourTime: () => Promise<boolean>
|
|
9
|
+
reduceMotion: () => Promise<boolean>
|
|
10
|
+
reduceTransparency: () => Promise<boolean>
|
|
11
|
+
increaseContrast: () => Promise<boolean>
|
|
12
|
+
systemVersion: () => Promise<string>
|
|
13
|
+
hostname: () => Promise<string>
|
|
14
|
+
username: () => Promise<string>
|
|
15
|
+
openPreferences: () => Promise<void>
|
|
16
|
+
}
|
package/dist/tags.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function installMockBridge(initialNamespaces?: string[]): MockBridgeHandle;
|
|
2
|
+
/** Helper — find the first captured call matching `ns` + `method`. */
|
|
3
|
+
export declare function findCall(calls: CapturedCall[], ns: string, method: string): CapturedCall | undefined;
|
|
4
|
+
export declare interface CapturedCall {
|
|
5
|
+
ns: string
|
|
6
|
+
method: string
|
|
7
|
+
args: unknown[]
|
|
8
|
+
}
|
|
9
|
+
export declare interface MockBridgeHandle {
|
|
10
|
+
calls: CapturedCall[]
|
|
11
|
+
whenCalled: (
|
|
12
|
+
ns: string,
|
|
13
|
+
method: string,
|
|
14
|
+
response: unknown | ((...args: unknown[]) => unknown)
|
|
15
|
+
) => void
|
|
16
|
+
uninstall: () => void
|
|
17
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/test-utils.ts
|
|
5
|
+
ensureWindowEventTarget();
|
|
6
|
+
function ensureWindowEventTarget() {
|
|
7
|
+
if (typeof window === "undefined")
|
|
8
|
+
return;
|
|
9
|
+
const w = window;
|
|
10
|
+
if (typeof w.addEventListener === "function" && typeof w.dispatchEvent === "function")
|
|
11
|
+
return;
|
|
12
|
+
const listeners = new Map;
|
|
13
|
+
w.addEventListener = (name, cb) => {
|
|
14
|
+
let set = listeners.get(name);
|
|
15
|
+
if (!set) {
|
|
16
|
+
set = new Set;
|
|
17
|
+
listeners.set(name, set);
|
|
18
|
+
}
|
|
19
|
+
set.add(cb);
|
|
20
|
+
};
|
|
21
|
+
w.removeEventListener = (name, cb) => {
|
|
22
|
+
listeners.get(name)?.delete(cb);
|
|
23
|
+
};
|
|
24
|
+
w.dispatchEvent = (event) => {
|
|
25
|
+
const set = listeners.get(event.type);
|
|
26
|
+
if (set) {
|
|
27
|
+
for (const fn of set) {
|
|
28
|
+
try {
|
|
29
|
+
fn(event);
|
|
30
|
+
} catch {}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function installMockBridge(initialNamespaces = []) {
|
|
37
|
+
const calls = [];
|
|
38
|
+
const responses = new Map;
|
|
39
|
+
const previousRaw = window.craft;
|
|
40
|
+
const previous = previousRaw && previousRaw.__craft_bridge_loaded ? undefined : previousRaw;
|
|
41
|
+
function makeMethod(ns, method) {
|
|
42
|
+
return (...args) => {
|
|
43
|
+
calls.push({ ns, method, args });
|
|
44
|
+
const key = `${ns}:${method}`;
|
|
45
|
+
if (responses.has(key)) {
|
|
46
|
+
const r = responses.get(key);
|
|
47
|
+
const resolved = typeof r === "function" ? r(...args) : r;
|
|
48
|
+
return Promise.resolve(resolved);
|
|
49
|
+
}
|
|
50
|
+
return Promise.resolve(undefined);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function makeNamespace(ns) {
|
|
54
|
+
return new Proxy({}, {
|
|
55
|
+
get(_target, prop) {
|
|
56
|
+
if (typeof prop !== "string")
|
|
57
|
+
return;
|
|
58
|
+
if (responses.has(`${ns}:${prop}`)) {
|
|
59
|
+
const r = responses.get(`${ns}:${prop}`);
|
|
60
|
+
if (typeof r === "function" && r.length === 0) {
|
|
61
|
+
return () => {
|
|
62
|
+
calls.push({ ns, method: prop, args: [] });
|
|
63
|
+
return r();
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return makeMethod(ns, prop);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const root = new Proxy({}, {
|
|
72
|
+
get(_target, prop) {
|
|
73
|
+
if (typeof prop !== "string")
|
|
74
|
+
return;
|
|
75
|
+
return makeNamespace(prop);
|
|
76
|
+
},
|
|
77
|
+
has(_target, prop) {
|
|
78
|
+
if (typeof prop !== "string")
|
|
79
|
+
return false;
|
|
80
|
+
if (initialNamespaces.length === 0)
|
|
81
|
+
return true;
|
|
82
|
+
return initialNamespaces.includes(prop);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
window.craft = root;
|
|
86
|
+
return {
|
|
87
|
+
calls,
|
|
88
|
+
whenCalled(ns, method, response) {
|
|
89
|
+
responses.set(`${ns}:${method}`, response);
|
|
90
|
+
},
|
|
91
|
+
uninstall() {
|
|
92
|
+
if (previous === undefined) {
|
|
93
|
+
delete window.craft;
|
|
94
|
+
} else {
|
|
95
|
+
window.craft = previous;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function findCall(calls, ns, method) {
|
|
101
|
+
return calls.find((c) => c.ns === ns && c.method === method);
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
installMockBridge,
|
|
105
|
+
findCall
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
//# debugId=112673127C3680E664756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/test-utils.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Test utilities — install a mock `window.craft` namespace + capture\n * every call against it. Apps consuming this package can `import {\n * installMockBridge } from '@stacksjs/desktop/test-utils'` to hand\n * their unit tests the same harness this package uses internally.\n *\n * The mock auto-vivifies namespaces on access — `craft.fs.readFile`\n * works without pre-declaring `fs`. Methods return a Promise resolving\n * to whatever was queued via `whenCalled`, defaulting to `undefined`.\n *\n * Tests should follow the install / call / assert / uninstall cycle:\n * ```ts\n * import { installMockBridge, findCall } from '@stacksjs/desktop/test-utils'\n * import { fs } from '@stacksjs/desktop'\n *\n * const bridge = installMockBridge()\n * bridge.whenCalled('fs', 'readFile', { data: 'hello' })\n * expect(await fs.readFile('/x')).toBe('hello')\n * expect(findCall(bridge.calls, 'fs', 'readFile')!.args).toEqual(['/x'])\n * bridge.uninstall()\n * ```\n *\n * Polyfills `window.addEventListener` / `dispatchEvent` for runners\n * (very-happy-dom, jsdom older versions) that don't ship them by\n * default — facade tests rely on those for event-based facades.\n */\n\nensureWindowEventTarget()\n\nfunction ensureWindowEventTarget(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (typeof w.addEventListener === 'function' && typeof w.dispatchEvent === 'function') return\n\n const listeners = new Map<string, Set<EventListener>>()\n\n w.addEventListener = (name: string, cb: EventListener): void => {\n let set = listeners.get(name)\n if (!set) {\n set = new Set()\n listeners.set(name, set)\n }\n set.add(cb)\n }\n\n w.removeEventListener = (name: string, cb: EventListener): void => {\n listeners.get(name)?.delete(cb)\n }\n\n w.dispatchEvent = (event: Event): boolean => {\n const set = listeners.get(event.type)\n if (set) {\n for (const fn of set) {\n try { fn(event) } catch { /* swallow listener errors during tests */ }\n }\n }\n return true\n }\n}\n\nexport interface CapturedCall {\n ns: string\n method: string\n args: unknown[]\n}\n\nexport interface MockBridgeHandle {\n /** Calls captured since the bridge was installed. */\n calls: CapturedCall[]\n /**\n * Queue the response from `window.craft[ns][method]`. The mock\n * walks: explicit return → matched response handler → default.\n */\n whenCalled: (\n ns: string,\n method: string,\n response: unknown | ((...args: unknown[]) => unknown)\n ) => void\n /** Remove the mock and restore whatever was on window.craft before. */\n uninstall: () => void\n}\n\nexport function installMockBridge(initialNamespaces: string[] = []): MockBridgeHandle {\n const calls: CapturedCall[] = []\n const responses = new Map<string, unknown | ((...args: unknown[]) => unknown)>()\n\n // If the production bridge IIFE has already loaded — flagged via\n // `__craft_bridge_loaded` — treat the existing window.craft as\n // \"no real previous.\" Otherwise restoring it on uninstall would\n // leak the production facade into \"no bridge\" assertions in\n // subsequent tests.\n const previousRaw = (window as any).craft\n const previous = previousRaw && previousRaw.__craft_bridge_loaded ? undefined : previousRaw\n\n function makeMethod(ns: string, method: string) {\n return (...args: unknown[]) => {\n calls.push({ ns, method, args })\n const key = `${ns}:${method}`\n if (responses.has(key)) {\n const r = responses.get(key)\n const resolved = typeof r === 'function'\n ? (r as (...a: unknown[]) => unknown)(...args)\n : r\n return Promise.resolve(resolved)\n }\n return Promise.resolve(undefined)\n }\n }\n\n function makeNamespace(ns: string): Record<string, unknown> {\n return new Proxy({} as Record<string, unknown>, {\n get(_target, prop: string) {\n if (typeof prop !== 'string') return undefined\n // Some non-method properties may be read synchronously (e.g.\n // theme.get returns an object, not a promise). Allow callers\n // to register those by passing a zero-arg function — we\n // recognize the shape and return the value synchronously.\n if (responses.has(`${ns}:${prop}`)) {\n const r = responses.get(`${ns}:${prop}`)\n if (typeof r === 'function' && r.length === 0) {\n return () => {\n calls.push({ ns, method: prop, args: [] })\n return (r as () => unknown)()\n }\n }\n }\n return makeMethod(ns, prop)\n },\n })\n }\n\n const root = new Proxy({} as Record<string, unknown>, {\n get(_target, prop: string) {\n if (typeof prop !== 'string') return undefined\n return makeNamespace(prop)\n },\n has(_target, prop) {\n if (typeof prop !== 'string') return false\n if (initialNamespaces.length === 0) return true\n return initialNamespaces.includes(prop)\n },\n })\n\n ;(window as any).craft = root\n\n return {\n calls,\n whenCalled(ns, method, response) {\n responses.set(`${ns}:${method}`, response)\n },\n uninstall() {\n if (previous === undefined) {\n delete (window as any).craft\n }\n else {\n ;(window as any).craft = previous\n }\n },\n }\n}\n\n/** Helper — find the first captured call matching `ns` + `method`. */\nexport function findCall(\n calls: CapturedCall[],\n ns: string,\n method: string,\n): CapturedCall | undefined {\n return calls.find(c => c.ns === ns && c.method === method)\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "112673127C3680E664756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const theme: SystemTheme;
|
|
2
|
+
export declare interface ThemeInfo {
|
|
3
|
+
appearance: Appearance
|
|
4
|
+
}
|
|
5
|
+
export declare interface SystemTheme {
|
|
6
|
+
get: () => ThemeInfo
|
|
7
|
+
onChange: (cb: (info: ThemeInfo) => void) => () => void
|
|
8
|
+
current: () => Promise<ThemeInfo>
|
|
9
|
+
}
|
|
10
|
+
export type Appearance = 'light' | 'dark';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const touchbar: TouchBarAPI;
|
|
2
|
+
export declare interface TouchBarItem {
|
|
3
|
+
id: string
|
|
4
|
+
type: TouchBarItemType
|
|
5
|
+
label?: string
|
|
6
|
+
icon?: string
|
|
7
|
+
value?: number
|
|
8
|
+
enabled?: boolean
|
|
9
|
+
segments?: Array<{ id: string, label?: string, icon?: string }>
|
|
10
|
+
}
|
|
11
|
+
export declare interface TouchBarActionEvent {
|
|
12
|
+
id: string
|
|
13
|
+
value?: number
|
|
14
|
+
segment?: string
|
|
15
|
+
}
|
|
16
|
+
export declare interface TouchBarAPI {
|
|
17
|
+
addItem: (item: TouchBarItem) => Promise<void>
|
|
18
|
+
removeItem: (id: string) => Promise<void>
|
|
19
|
+
updateItem: (id: string, props: Partial<TouchBarItem>) => Promise<void>
|
|
20
|
+
setLabel: (id: string, label: string) => Promise<void>
|
|
21
|
+
setIcon: (id: string, icon: string) => Promise<void>
|
|
22
|
+
setEnabled: (id: string, enabled: boolean) => Promise<void>
|
|
23
|
+
setSliderValue: (id: string, value: number) => Promise<void>
|
|
24
|
+
clear: () => Promise<void>
|
|
25
|
+
show: () => Promise<void>
|
|
26
|
+
hide: () => Promise<void>
|
|
27
|
+
onAction: (cb: (event: TouchBarActionEvent) => void) => () => void
|
|
28
|
+
}
|
|
29
|
+
export type TouchBarItemType = 'button' | 'label' | 'slider' | 'spacer' | 'colorPicker' | 'segmented';
|