crossbind 2.0.0-beta.68 → 2.0.0-beta.69

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.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/package.json +69 -59
  3. package/src/actions/addExtension.js +191 -0
  4. package/src/actions/androidGradle.js +26 -17
  5. package/src/actions/appInstaller.js +69 -153
  6. package/src/actions/appSwift.js +66 -0
  7. package/src/actions/buildApp.js +172 -74
  8. package/src/actions/buildNode.js +6 -1
  9. package/src/actions/buildWasm.js +0 -9
  10. package/src/actions/createInterface.js +17 -8
  11. package/src/actions/createLib.js +0 -4
  12. package/src/actions/extensionApi.js +298 -0
  13. package/src/actions/extensionCommands.js +41 -0
  14. package/src/actions/extensionsInApp.js +19 -0
  15. package/src/actions/gradleProject.js +196 -16
  16. package/src/actions/iosDevice.js +2 -2
  17. package/src/actions/iosSimulator.js +3 -3
  18. package/src/actions/licenses.js +83 -34
  19. package/src/actions/linuxPackages.js +48 -0
  20. package/src/actions/mavenVerification.js +37 -0
  21. package/src/actions/publish.js +220 -0
  22. package/src/actions/windowsSigning.js +1 -1
  23. package/src/actions/xcodeProject.js +49 -24
  24. package/src/actions/xcodeTargets.js +122 -0
  25. package/src/actions/xcodebuild.js +65 -0
  26. package/src/app/index.d.ts +126 -133
  27. package/src/app/index.js +126 -188
  28. package/src/assets/configure/install.sh +0 -0
  29. package/src/assets/toolchain-digests.json +20 -20
  30. package/src/bin.js +20 -28
  31. package/src/index.js +2 -1
  32. package/src/program.js +32 -3
  33. package/src/state/index.js +2 -1
  34. package/src/state/loadConfig.js +16 -5
  35. package/src/utils/appExtensions.js +761 -0
  36. package/src/utils/appFiles.js +58 -0
  37. package/src/utils/appLaunches.js +249 -0
  38. package/src/utils/appOptions.js +109 -100
  39. package/src/utils/appTargets.js +168 -0
  40. package/src/utils/bridgeTools.js +66 -0
  41. package/src/utils/configChanges.js +30 -0
  42. package/src/utils/configWriter.js +143 -26
  43. package/src/utils/extensionSteps.js +135 -0
  44. package/src/utils/openUrl.js +2 -1
  45. package/src/utils/plist.js +5 -0
  46. package/src/utils/resolveAppHost.js +7 -0
  47. package/src/utils/systemConfig.js +16 -3
  48. package/vitest.config.js +6 -1
  49. package/src/actions/appSetup.js +0 -116
  50. package/src/actions/appStoreConnect.js +0 -188
  51. package/src/actions/appUpdate.js +0 -68
  52. package/src/actions/extensions.js +0 -7
  53. package/src/actions/googlePlay.js +0 -213
  54. package/src/actions/googleSignIn.js +0 -78
  55. package/src/actions/playSetup.js +0 -19
  56. package/src/actions/publishAndroid.js +0 -102
  57. package/src/actions/publishIos.js +0 -146
@@ -1,171 +1,164 @@
1
- // What an app's host does for its page (target.runtimeEnv: 'app'); in any other build every call rejects.
1
+ // What an app's host does for its page (target.runtimeEnv: 'app'): crossbind/app/core alone, which crossbind/app has with
2
+ // what crossbind's own extensions give the page. A TypeScript app has their types with
3
+ // /// <reference types="@crossbind/core-app-host/app" />.
2
4
 
3
- /** A kind of file a dialog offers: its name, and the extensions, with or without the dot, that make it; "*" is any file. */
4
- export interface FileFilter {
5
- name: string;
6
- extensions: string[];
7
- }
8
-
9
- export interface OpenOptions {
10
- title?: string;
11
- /** The folder the dialog shows first. */
12
- defaultPath?: string;
13
- filters?: FileFilter[];
14
- /** Folders instead of files. */
15
- directory?: boolean;
16
- multiple?: boolean;
17
- }
18
-
19
- export interface SaveOptions {
20
- title?: string;
21
- /** The folder the dialog shows first. */
22
- defaultPath?: string;
23
- defaultName?: string;
24
- filters?: FileFilter[];
25
- }
26
-
27
- export interface MessageOptions {
28
- message: string;
29
- /** Smaller text under the message. */
30
- detail?: string;
31
- /** info by default. Windows shows its icon for each, and macOS a caution sign for error; Linux, iOS and Android show none. */
32
- kind?: 'info' | 'warning' | 'error';
33
- /** One to three labels, the first the default; without them OK. */
34
- buttons?: string[];
35
- }
36
-
37
- /** The app's own folders, made when first asked for: what it keeps, what it can lose, and its logs. */
5
+ /** The app's own folders, made when first asked for: what it keeps, what it can lose, and its logs; and the read-only one of the files app.files lists, each in the place it had in the project. */
38
6
  export interface AppPaths {
39
7
  data: string;
40
8
  cache: string;
41
9
  logs: string;
10
+ resources: string;
11
+ /** An iOS app's App Group's folder, which the targets of its extensions' that ask for it with appGroup: true share; '' elsewhere. */
12
+ group: string;
42
13
  }
43
14
 
44
- export declare const dialog: {
45
- /** The paths of the files or folders the user picked, or null when they cancelled. */
46
- open(options?: OpenOptions): Promise<string[] | null>;
47
- /** The path the user chose to save to, or null when they cancelled. */
48
- save(options?: SaveOptions): Promise<string | null>;
49
- /** The index of the button the user clicked: Return gives the first, and Escape or closing the dialog the last. */
50
- message(options: MessageOptions): Promise<number>;
51
- };
52
-
53
- export declare const shell: {
54
- /** An http, https or mailto address in the default browser or mail app. */
55
- openExternal(url: string | URL): Promise<void>;
56
- /** A file in the app the system opens its kind with, where app.openPath in crossbind.config.js lets the page: nowhere without it. */
57
- openPath(path: string): Promise<void>;
58
- /** A file, selected, in the system's file manager: one in the app's folders, or one a dialog picked during this run. */
59
- revealInFolder(path: string): Promise<void>;
60
- /** A file or folder moved to the system's trash, where its user can take it back: one in the app's folders, not one of them itself, or one a dialog picked during this run. Where the system has no trash, nothing moves and it rejects. */
61
- trash(path: string): Promise<void>;
62
- };
63
-
64
15
  export declare const app: {
65
16
  paths(): Promise<AppPaths>;
66
17
  /** Ends the app as closing its window does. */
67
18
  quit(): Promise<void>;
19
+ /** Asks the app's extensions, as its user's Quit does, then ends the app as quit() does, unless one keeps it running. It resolves once it has asked the host, before the answer. */
20
+ requestQuit(): Promise<void>;
68
21
  /** Ends the app as quit() does, then opens it again, with no link. */
69
22
  relaunch(): Promise<void>;
70
- /** The links of app.urlSchemes in crossbind.config.js that opened the app and have not reached the page yet, the one it was launched with among them. Once the page has asked, each later link comes as the event open-url while it listens, so listening first, then asking, misses none. */
71
- launchUrls(): Promise<string[]>;
23
+ /** The launch that started a desktop app. A phone's has no arguments, and no folder. */
24
+ launchArgs(): Promise<Launch>;
72
25
  };
73
26
 
74
- /** A key with CmdOrCtrl, Ctrl or Alt and maybe Shift, joined by +, as CmdOrCtrl+Shift+O is, or F1–F12, alone or with any of them. The key is A–Z, 0–9, F1–F12, Enter, Escape, Tab, Space, Backspace, Delete, Up, Down, Left, Right, Home, End, PageUp, PageDown, Plus, Minus, Comma or Period. */
75
- export type Accelerator = string;
76
-
77
- /** An item of a menu: one the page handles, by its id, a submenu, a separator, or a standard one by its role. */
78
- export type MenuItem =
79
- | { label: string; id?: string; accelerator?: Accelerator; enabled?: boolean; checked?: boolean }
80
- | { label: string; items: MenuItem[] }
81
- | { type: 'separator' }
82
- | { role: 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'selectAll'; label?: string; accelerator?: never }
83
- | { role: 'minimize' | 'close' | 'quit'; label?: string; accelerator?: Accelerator }
84
- | { role: 'editMenu' | 'windowMenu'; label?: string };
85
-
86
- /** A menu of the bar, by its items, or a standard one by its role. */
87
- export type Menu = { label: string; items: MenuItem[] } | { role: 'editMenu' | 'windowMenu'; label?: string };
88
-
89
- /** What the event menu carries: the id of the item clicked, and for one with checked whether it now is. */
90
- export interface MenuClick {
91
- id: string;
92
- checked?: boolean;
27
+ /** What windows.set() changes of an open window: sizes and places in logical pixels, a page's size without the frame, and x and y the frame's place from the top left of the main screen, given together. A limit of 0 takes it away. */
28
+ export interface WindowChanges {
29
+ title?: string;
30
+ width?: number;
31
+ height?: number;
32
+ x?: number;
33
+ y?: number;
34
+ /** Moves the window to the middle of its screen. */
35
+ center?: boolean;
36
+ minWidth?: number;
37
+ minHeight?: number;
38
+ maxWidth?: number;
39
+ maxHeight?: number;
40
+ resizable?: boolean;
41
+ /** Keeps the window above the other apps' windows. */
42
+ alwaysOnTop?: boolean;
43
+ fullscreen?: boolean;
93
44
  }
94
45
 
95
- export declare const menu: {
96
- /** Sets the app's menus: on macOS after its app menu, which the app keeps, and on Windows and Linux in a bar of its window. A click of an item with an id is an event, menu, with a MenuClick. */
97
- set(menus: Menu[]): Promise<void>;
98
- };
46
+ /** What a window opens with: app.window's options, beside the page it loads and its name. Without x and y it opens in the middle of the screen. */
47
+ export interface WindowOptions extends Omit<WindowChanges, 'center' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'> {
48
+ /** The app's own page, as /settings.html?tab=2: '/' by default. */
49
+ path?: string;
50
+ /** A name of the app's own: a window of a name already open comes to the front, and no other opens. */
51
+ name?: string;
52
+ minWidth?: number;
53
+ minHeight?: number;
54
+ maxWidth?: number;
55
+ maxHeight?: number;
56
+ /** What the window shows until the page paints, as #rrggbb: app.window's by default. */
57
+ backgroundColor?: string;
58
+ /** false opens a window without a title bar and its buttons, which the page moves with data-crossbind-drag or windows.startDrag(). */
59
+ frame?: boolean;
60
+ /** The id of the window it stays above, and closes with. */
61
+ parent?: number;
62
+ /** With a parent: a sheet of the parent's on macOS, and on Windows and Linux a window the parent takes no input under until it closes. */
63
+ modal?: boolean;
64
+ }
99
65
 
100
- /** An item of the tray's menu: one the page handles, by its id, a submenu or a separator. */
101
- export type TrayItem =
102
- | { label: string; id?: string; enabled?: boolean; checked?: boolean }
103
- | { label: string; items: TrayItem[] }
104
- | { type: 'separator' };
105
-
106
- export interface TrayOptions {
107
- /** What the icon shows when the pointer rests on it. */
108
- tooltip?: string;
109
- /** The menu a click of the icon opens: a click on macOS, a right click on Windows, and on Linux the one its desktop takes. */
110
- menu?: TrayItem[];
66
+ /** An open window, as windows.list() tells of it. */
67
+ export interface WindowState {
68
+ id: number;
69
+ name: string | null;
70
+ title: string;
71
+ x: number;
72
+ y: number;
73
+ width: number;
74
+ height: number;
75
+ isMaximized: boolean;
76
+ isMinimized: boolean;
77
+ isFullscreen: boolean;
78
+ isFocused: boolean;
111
79
  }
112
80
 
113
- export declare const tray: {
114
- /** The app's icon in the macOS menu bar, the Windows notification area or a Linux desktop's status tray. A click of an item with an id is the event menu, with a MenuClick, and a click of the icon the event tray where it opens no menu. Set again, it changes the icon that shows. */
115
- set(options?: TrayOptions): Promise<void>;
116
- /** Takes the icon away. */
117
- remove(): Promise<void>;
118
- };
81
+ /** What windows.open() and windows.set() answer: the window's id, and the options the platform could not honour, which it did without, as Wayland's x and y. */
82
+ export interface WindowOpened {
83
+ id: number;
84
+ ignored: string[];
85
+ }
119
86
 
120
- export interface NotificationOptions {
121
- title: string;
122
- body?: string;
87
+ /** What the events window-opened and window-closed carry. */
88
+ export interface WindowEvent {
89
+ id: number;
90
+ name: string | null;
123
91
  }
124
92
 
125
- export declare const notification: {
126
- /** A notification of the system's; a click on it is the event notification. macOS asks its user first. */
127
- show(options: NotificationOptions): Promise<void>;
93
+ export declare const windows: {
94
+ /** Opens a window of the app's own page, in front, on the desktop and an iPad whose app.ios.multipleWindows is true; an iPhone and Android reject. */
95
+ open(options?: WindowOptions): Promise<WindowOpened>;
96
+ /** Changes the window of this id, or the page's own without one. */
97
+ set(changes: WindowChanges): Promise<{ ignored: string[] }>;
98
+ set(id: number, changes: WindowChanges): Promise<{ ignored: string[] }>;
99
+ /** Closes the window of this id, or the page's own without one, as its user does: an extension may keep it open. The app quits as its last window closes. */
100
+ close(id?: number): Promise<void>;
101
+ /** Brings the window of this id, or the page's own without one, to the front, restored if it was minimized. */
102
+ focus(id?: number): Promise<void>;
103
+ minimize(id?: number): Promise<void>;
104
+ toggleMaximize(id?: number): Promise<void>;
105
+ /** Moves the page's window with the pointer, as its title bar does, from a mousedown of the primary button. */
106
+ startDrag(): Promise<void>;
107
+ /** The open windows, the oldest first. */
108
+ list(): Promise<WindowState[]>;
109
+ /** The page's own window. */
110
+ current(): Promise<WindowState>;
128
111
  };
129
112
 
130
- /** What the event second-instance carries: a later launch's arguments, the program's own left out, and the folder it was launched in. */
131
- export interface SecondInstance {
113
+ /** A launch of a desktop app: its arguments, the program's own and its links left out, which reach the owners of their schemes, the page those of app.urlSchemes as the event open-url; and the folder it was launched in. */
114
+ export interface Launch {
132
115
  args: string[];
133
116
  cwd: string;
134
117
  }
135
118
 
136
- /** What the event open-url carries: a link of one of app.urlSchemes that the system opened the app with. */
137
- export interface OpenUrl {
138
- url: string;
119
+ /** What each event a page's listeners get gives them, by the event's name: the host's own here, and those an extension's types add. */
120
+ export interface AppEvents {
121
+ /** Calls listener as the app becomes the active one on the desktop, or comes to a phone's foreground, until the function it returns is called. A Linux app's is its window's focus. */
122
+ 'active': void;
123
+ /** Calls listener as another app takes the app's place on the desktop, or a phone's is interrupted, as by a call, a system alert or another app's picker, or goes to the background, until the function it returns is called. */
124
+ 'inactive': void;
125
+ /** Calls listener as each window of the app's opens, until the function it returns is called. */
126
+ 'window-opened': WindowEvent;
127
+ /** Calls listener as each window of the app's closes, until the function it returns is called. */
128
+ 'window-closed': WindowEvent;
139
129
  }
140
130
 
131
+ /** What each event the host holds for the page gives, by the event's name, which an extension's types add. */
132
+ export interface HeldEvents {}
133
+
141
134
  export declare const events: {
142
- /** Calls listener with each click of an item with an id in the menus menu.set sets or in the tray's menu, until the function it returns is called. */
143
- on(name: 'menu', listener: (click: MenuClick) => void): () => void;
144
- /** Calls listener with each link of app.urlSchemes the system opens the app with once the page has called app.launchUrls(), until the function it returns is called. */
145
- on(name: 'open-url', listener: (open: OpenUrl) => void): () => void;
146
- /** Calls listener with each later launch of a desktop app that app.singleInstance keeps to one instance, which brings its window to the front as far as the system lets it, until the function it returns is called. */
147
- on(name: 'second-instance', listener: (launch: SecondInstance) => void): () => void;
148
- /** Calls listener as the system of a desktop app goes to sleep, which it may do before the page has run, until the function it returns is called. */
149
- on(name: 'suspend', listener: () => void): () => void;
150
- /** Calls listener as the system of a desktop app wakes from sleep, until the function it returns is called. */
151
- on(name: 'resume', listener: () => void): () => void;
152
- /** Calls listener with each left or right click of the tray's icon that opens no menu, until the function it returns is called. */
153
- on(name: 'tray', listener: () => void): () => void;
154
- /** Calls listener with each click on a notification the app's notification.show showed while it runs, until the function it returns is called. */
155
- on(name: 'notification', listener: () => void): () => void;
135
+ on<Name extends keyof AppEvents>(name: Name, listener: (value: AppEvents[Name]) => void): () => void;
156
136
  /** Calls listener with the value of each event of this name the app's native code emits from now on, until the function it returns is called. */
157
137
  on(name: string, listener: (value: unknown) => void): () => void;
138
+ held<Name extends keyof HeldEvents>(name: Name): Promise<HeldEvents[Name][]>;
139
+ /** The values of the events of this name the app's native code held for the page with holdEvent(), which came before the page asked for them since it loaded; later ones come as the events while it listens, so listening first, then asking, misses none. */
140
+ held(name: string): Promise<unknown[]>;
158
141
  };
159
142
 
160
- /** A newer version of the app, which app.updater.url in crossbind.config.js offers. */
161
- export interface Update {
162
- version: string;
143
+ /** What an option of a page's function is, beside what typeof tells: how it is checked, and what it is called. */
144
+ export interface OptionKind {
145
+ isFitting(value: unknown): boolean;
146
+ name: string;
163
147
  }
164
148
 
165
- /** One check or install runs at a time, and another rejects meanwhile. */
166
- export declare const updater: {
167
- /** The version app.updater.url offers when it is newer than the app's, or null. */
168
- check(): Promise<Update | null>;
169
- /** Downloads that version, checks that the key of app.updater.publicKey signed it and installs it in place of the app, which then quits and opens the new version. It rejects when that fails. */
170
- install(): Promise<void>;
171
- };
149
+ /** The options as the host takes them, so a misspelt or mistyped one fails here, saying which. */
150
+ export declare function checkedOptions<T>(name: string, options: T, kinds: Record<string, string | OptionKind>): T;
151
+
152
+ /** What invoke takes beside a function's options. */
153
+ export interface InvokeOptions<M = unknown> {
154
+ /** Gets each message the function sends before it answers, in the order it sent them, all of them before invoke resolves. */
155
+ onMessage?: (message: M) => void;
156
+ /** Cancels the call: invoke rejects with the signal's reason, and the function hears of it. A new page cancels each call of the one before. */
157
+ signal?: AbortSignal;
158
+ }
159
+
160
+ /** A function of one of the app's extensions, by its name, as clipboard.readText, with options of JSON values and bytes, a typed array, a DataView or an ArrayBuffer, whose result's bytes come back as a Uint8Array; an extension's own package calls it so. */
161
+ export declare function invoke<T = unknown, M = unknown>(name: string, options?: Record<string, unknown>, call?: InvokeOptions<M>): Promise<T>;
162
+
163
+ /** The URL of a path an extension's route serves, as "/clips/intro.mp4" or "/thumb/42?size=256", for the page's <img>, <video> or fetch(): crossbind://app/ext/<extension><path>, and https://appassets.androidplatform.net/ext/<extension><path> on Android. The path is as a URL holds it, escaped where it must be, without a part "." or ".."; the route gets it decoded. */
164
+ export declare function routeUrl(extension: string, path: string): string;