@omega.js/desktop 0.52.0 → 0.53.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 +17 -12
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli.js +1 -1
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/clean.js +2 -2
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/install.js +3 -3
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +6 -6
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +3 -3
- package/dist/commands/runner.js +11 -11
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +2 -2
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/AGENTS.md +17 -8
- package/dist/defaults/config/omega.json5 +7 -7
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/integrations/context-menu/index.js +2 -2
- package/dist/defaults/src/integrations/menu/index.js +3 -3
- package/dist/defaults/src/integrations/tray/index.js +3 -3
- package/dist/defaults/src/main.js +3 -5
- package/dist/defaults/src/preload.js +3 -5
- package/dist/defaults/test/README.md +2 -2
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +7 -7
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +28 -28
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +398 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +1 -1
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/cli.test.js +2 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-scaffold.test.js +2 -2
- package/dist/test/suites/build/deploy-hook.test.js +3 -3
- package/dist/test/suites/build/ensure-target.test.js +2 -2
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +1 -1
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner.test.js +2 -2
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +2 -2
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +27 -7
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +8 -11
- package/dist/vendor/config/load.js +1 -2
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/retired-keys.js +2 -2
- package/dist/vendor/config/schema.js +5 -8
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +1 -2
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/attach-log-file.js +1 -1
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/cli-router.js +3 -4
- package/dist/vendor/devkit/defaults-engine.js +9 -11
- package/dist/vendor/devkit/local.js +2 -0
- package/dist/vendor/devkit/merge-line-files.js +2 -3
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/docs/analytics.md +8 -8
- package/docs/app-state.md +19 -19
- package/docs/audit.md +4 -4
- package/docs/{client-bridge.md → auth.md} +88 -73
- package/docs/auto-updater.md +8 -8
- package/docs/boot-sequence.md +11 -6
- package/docs/build-system.md +1 -1
- package/docs/cdp-debugging.md +1 -1
- package/docs/common-mistakes.md +7 -7
- package/docs/config-schema.md +1 -1
- package/docs/context-menu.md +13 -13
- package/docs/context.md +11 -11
- package/docs/css.md +3 -9
- package/docs/deep-link.md +25 -25
- package/docs/environment-detection.md +16 -16
- package/docs/fontawesome.md +7 -5
- package/docs/hooks.md +8 -8
- package/docs/index.md +38 -27
- package/docs/ipc.md +10 -10
- package/docs/lib-modules.md +9 -9
- package/docs/logging.md +12 -14
- package/docs/menu.md +18 -18
- package/docs/remote-config.md +9 -9
- package/docs/remote-scripts.md +12 -12
- package/docs/restart-manager.md +8 -8
- package/docs/sentry.md +4 -4
- package/docs/shared/analytics.md +1 -1
- package/docs/shared/breaking-changes.md +79 -13
- package/docs/shared/config.md +17 -21
- package/docs/shared/logging.md +1 -1
- package/docs/shared/monitoring.md +5 -5
- package/docs/shared/testing.md +2 -2
- package/docs/shared/theming.md +1 -1
- package/docs/shared/translation.md +19 -10
- package/docs/startup.md +16 -16
- package/docs/storage.md +11 -11
- package/docs/templating.md +3 -3
- package/docs/test-boot-layer.md +12 -12
- package/docs/test-framework.md +17 -17
- package/docs/themes.md +7 -7
- package/docs/tooltips.md +2 -2
- package/docs/tray.md +31 -31
- package/docs/usage.md +7 -7
- package/docs/verts.md +1 -1
- package/docs/windows.md +22 -22
- package/package.json +3 -4
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
package/docs/context.md
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Runtime info block. Mirrors @omega.js/backend's `assistant.request.{geolocation,client}` shape so @omega.js/desktop apps + sister projects (@omega.js/backend, UJM, @omega.js/client) all reference the same property paths when reading user info.
|
|
4
4
|
|
|
5
|
-
Populated asynchronously during `
|
|
5
|
+
Populated asynchronously during `omega.initialize()`.
|
|
6
6
|
|
|
7
7
|
## Shape
|
|
8
8
|
|
|
9
9
|
```js
|
|
10
|
-
|
|
10
|
+
omega.context.geolocation = {
|
|
11
11
|
ip: '203.0.113.42', // async-fetched via ipify
|
|
12
12
|
country: null, // future enhancement
|
|
13
13
|
region: null,
|
|
14
14
|
city: null,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
omega.context.client = {
|
|
18
18
|
userAgent: 'Mozilla/5.0 ...', // app.userAgentFallback
|
|
19
19
|
locale: 'en-US', // app.getLocale()
|
|
20
20
|
platform: 'darwin', // os.platform()
|
|
@@ -22,15 +22,15 @@ manager.context.client = {
|
|
|
22
22
|
mobile: false, // always false on @omega.js/desktop (desktop framework)
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
omega.context.session = {
|
|
26
26
|
id: '<uuid>', // fresh per launch (crypto.randomUUID)
|
|
27
27
|
startTime: '2026-05-08T...', // ISO at boot
|
|
28
28
|
deviceId: '<uuid or MAC>', // stable per-machine
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
version: '1.2.3', //
|
|
33
|
-
environment: 'production', //
|
|
31
|
+
omega.context.app = {
|
|
32
|
+
version: '1.2.3', // omega.getVersion()
|
|
33
|
+
environment: 'production', // omega.getEnvironment()
|
|
34
34
|
isPackaged: true, // app.isPackaged
|
|
35
35
|
};
|
|
36
36
|
```
|
|
@@ -54,9 +54,9 @@ Failure mode: a failed ipify fetch leaves the previous cached value untouched. T
|
|
|
54
54
|
## API
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const snap =
|
|
57
|
+
omega.context.geolocation.ip // direct read
|
|
58
|
+
omega.context.session.deviceId // direct read
|
|
59
|
+
const snap = omega.context.toJSON(); // structured-cloneable snapshot
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
Renderer:
|
|
@@ -71,7 +71,7 @@ console.log(snap.session.deviceId);
|
|
|
71
71
|
Sister projects (@omega.js/backend, @omega.js/client, UJM) all reference paths like `assistant.request.geolocation.country` and `assistant.request.client.userAgent`. @omega.js/desktop matches the leaf names so consumer code can write logic that works across all four runtimes:
|
|
72
72
|
|
|
73
73
|
```js
|
|
74
|
-
const country =
|
|
74
|
+
const country = omega.context.geolocation.country
|
|
75
75
|
|| assistant.request.geolocation.country // @omega.js/backend
|
|
76
76
|
|| omega.context.geolocation.country;
|
|
77
77
|
```
|
package/docs/css.md
CHANGED
|
@@ -32,7 +32,7 @@ Compiles to `dist/assets/css/main.bundle.css` (Bootstrap + classy theme + your g
|
|
|
32
32
|
|
|
33
33
|
## Theme integration
|
|
34
34
|
|
|
35
|
-
The `@use 'omega-desktop'` entry pulls in Bootstrap 5 + @omega.js/desktop's classy theme. Appearance (`system`/`light`/`dark`) defaults from `config.theme.appearance` and is applied + kept live on `<html data-bs-theme>` by `
|
|
35
|
+
The `@use 'omega-desktop'` entry pulls in Bootstrap 5 + @omega.js/desktop's classy theme. Appearance (`system`/`light`/`dark`) defaults from `config.theme.appearance` and is applied + kept live on `<html data-bs-theme>` by `omega.theme` (OS-following, runtime-switchable, persisted override, see [themes.md](themes.md)). Theme variables (`$primary`, `$dark`, `$classy-bg-*`, typography, borders) are overridable via the `with (...)` block, and `$primary` arrives from `brand.color` through the generated `dist/assets/scss/_brand.scss` unless a literal replaces `brand.$primary` ([#912](https://github.com/Omega-JS-Stack/omega/issues/912)). See [themes.md](themes.md) for the full variable reference.
|
|
36
36
|
|
|
37
37
|
## Icon presentation
|
|
38
38
|
|
|
@@ -69,15 +69,9 @@ Emit this markup in the window's HTML:
|
|
|
69
69
|
</div>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
The renderer instance wires the behavior during `omega.initialize()` (the vendored `__main_assets__/js/core/app-shell.js`, the same module @omega.js/web runs), so a view that renders the markup needs no script of its own. The API is `omega.shell` (`isCollapsed`, `isOpen`, `setCollapsed`, `setOpen`, `toggleCollapsed`, `toggleOpen`).
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
import appShell from '__main_assets__/js/core/app-shell.js';
|
|
76
|
-
|
|
77
|
-
appShell();
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The module is delegated and declarative: `[data-shell-toggle="collapse"]` toggles the rail, `[data-shell-toggle="drawer"]` toggles the mobile drawer, `[data-shell-dismiss]` (and Escape) closes it. It stamps the state on the container — `data-shell-collapsed="true"` (persisted under the `shell.collapsed` storage key) and `data-shell-open="true"` — which is what the CSS keys off; the API is also registered at `omega._library.appShell`. Add `.omega-shell--locked` when `main` should never scroll (the page manages its own interior scroll).
|
|
74
|
+
The module is delegated and declarative: `[data-shell-toggle="collapse"]` toggles the rail, `[data-shell-toggle="drawer"]` toggles the mobile drawer, `[data-shell-dismiss]` (and Escape) closes it. It stamps the state on the container: `data-shell-collapsed="true"` (persisted under the `shell.collapsed` storage key) and `data-shell-open="true"`, which is what the CSS keys off. Add `.omega-shell--locked` when `main` should never scroll (the page manages its own interior scroll).
|
|
81
75
|
|
|
82
76
|
## Bootstrap-first convention
|
|
83
77
|
|
package/docs/deep-link.md
CHANGED
|
@@ -10,7 +10,7 @@ Cross-platform deep-link handling that's simple to use and hard to get wrong. @o
|
|
|
10
10
|
}
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
@omega.js/desktop registers each scheme with the OS via `app.setAsDefaultProtocolClient` so the system routes matching URLs to your app. Registration is **production-only
|
|
13
|
+
@omega.js/desktop registers each scheme with the OS via `app.setAsDefaultProtocolClient` so the system routes matching URLs to your app. Registration is **production-only**: dev/test runs never claim OS-wide protocol handlers for unpackaged Electron binaries. In dev, exercise your handlers with `omega.deepLink.dispatch(url)` instead.
|
|
14
14
|
|
|
15
15
|
## How it works (so you don't have to think about it)
|
|
16
16
|
|
|
@@ -20,15 +20,15 @@ Cross-platform deep-link handling that's simple to use and hard to get wrong. @o
|
|
|
20
20
|
| **Windows** | URL appended to `process.argv`; @omega.js/desktop extracts it | OS forwards argv to the existing instance via `app.on('second-instance')`; @omega.js/desktop reads the duplicate's real argv from that event's `additionalData` |
|
|
21
21
|
| **Linux** | Same as Windows | Same as Windows |
|
|
22
22
|
|
|
23
|
-
@omega.js/desktop handles all of these and dispatches them through the same `
|
|
23
|
+
@omega.js/desktop handles all of these and dispatches them through the same `omega.deepLink.on()` event registry. Your code looks identical regardless of platform or cold/warm start. Single-instance lock is acquired automatically (via `lib/protocol.js`); duplicate launches exit cleanly and forward their argv to the original instance.
|
|
24
24
|
|
|
25
25
|
## Public API
|
|
26
26
|
|
|
27
27
|
```js
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
omega.deepLink.on(pattern, handler) // register a handler. Returns unsubscribe fn.
|
|
29
|
+
omega.deepLink.off(pattern, handler)
|
|
30
|
+
omega.deepLink.dispatch(url) // manually fire (testing, custom triggers)
|
|
31
|
+
omega.deepLink.getColdStartUrl() // the URL the app was launched with, or null
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## Patterns
|
|
@@ -43,7 +43,7 @@ manager.deepLink.getColdStartUrl() // the URL the app was launched with, o
|
|
|
43
43
|
## Handler signature
|
|
44
44
|
|
|
45
45
|
```js
|
|
46
|
-
|
|
46
|
+
omega.deepLink.on('user/profile/:id', (ctx) => {
|
|
47
47
|
ctx.url // 'myapp://user/profile/42?ref=tray'
|
|
48
48
|
ctx.scheme // 'myapp'
|
|
49
49
|
ctx.route // 'user/profile/42'
|
|
@@ -63,16 +63,16 @@ manager.deepLink.on('user/profile/:id', (ctx) => {
|
|
|
63
63
|
|
|
64
64
|
| Route | Default behavior |
|
|
65
65
|
|---|---|
|
|
66
|
-
| `auth/token` | Calls `
|
|
67
|
-
| `app/show` | `
|
|
66
|
+
| `auth/token` | Calls `omega.auth.handleToken(query.authToken)`: the receiving end of the `omega.openAuthFlow()` sign-in round-trip. MODERN shape only (`?authToken=`, what the website's token page sends); other formats (`?token=`, `?payload=`) are ignored. In production the URL arrives via the OS scheme; in dev/test `lib/auth-flow.js`'s loopback listener dispatches the same URL manually (the scheme isn't OS-registered in dev: protocol.js registers only in production, and macOS can't runtime-register unlisted schemes at all) |
|
|
67
|
+
| `app/show` | `omega.windows.show(query.window || 'main')` |
|
|
68
68
|
| `app/quit` | `app.quit()` |
|
|
69
69
|
|
|
70
70
|
### Overriding a built-in
|
|
71
71
|
|
|
72
72
|
```js
|
|
73
73
|
// Replace the built-in app/show with custom logic.
|
|
74
|
-
|
|
75
|
-
if (ctx.query.window === 'admin' && !
|
|
74
|
+
omega.deepLink.on('app/show', (ctx) => {
|
|
75
|
+
if (ctx.query.window === 'admin' && !omega.appState.isAdminUser()) {
|
|
76
76
|
showError('not authorized');
|
|
77
77
|
ctx.handled = true; // suppress built-in
|
|
78
78
|
return;
|
|
@@ -96,9 +96,9 @@ Setting `ctx.handled = true` in any handler stops the cascade. Within a single t
|
|
|
96
96
|
### Route to a window + send IPC
|
|
97
97
|
|
|
98
98
|
```js
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
omega.deepLink.on('user/profile/:id', (ctx) => {
|
|
100
|
+
omega.windows.show('main');
|
|
101
|
+
omega.windows.get('main').webContents.send('navigate', {
|
|
102
102
|
to: `/profile/${ctx.params.id}`,
|
|
103
103
|
});
|
|
104
104
|
});
|
|
@@ -107,17 +107,17 @@ manager.deepLink.on('user/profile/:id', (ctx) => {
|
|
|
107
107
|
### Catch-all logger
|
|
108
108
|
|
|
109
109
|
```js
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
omega.deepLink.on('*', (ctx) => {
|
|
111
|
+
omega.logger.warn(`Unrouted deep link: ${ctx.url}`);
|
|
112
112
|
});
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
### Cold-start branching
|
|
116
116
|
|
|
117
117
|
```js
|
|
118
|
-
const coldUrl =
|
|
118
|
+
const coldUrl = omega.deepLink.getColdStartUrl();
|
|
119
119
|
if (coldUrl) {
|
|
120
|
-
|
|
120
|
+
omega.logger.log(`Launched from deep link: ${coldUrl}`);
|
|
121
121
|
// appState.launchedFromDeepLink() is also set automatically
|
|
122
122
|
}
|
|
123
123
|
```
|
|
@@ -127,13 +127,13 @@ if (coldUrl) {
|
|
|
127
127
|
```js
|
|
128
128
|
tray.item({
|
|
129
129
|
label: 'Open Profile',
|
|
130
|
-
click: () =>
|
|
130
|
+
click: () => omega.deepLink.dispatch('myapp://user/profile/me'),
|
|
131
131
|
});
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
## Boot queueing
|
|
135
135
|
|
|
136
|
-
Every dispatch is held until `
|
|
136
|
+
Every dispatch is held until `omega.initialize()` completes (main.js calls `deepLink.markOmegaReady()` as its last step). A cold-start `auth/token` link (the OS launching the app from the sign-in round trip) therefore never fires before `omega.auth` has Firebase up; it queues and drains the moment the instance is ready. Warm-start dispatches on a running app pass straight through.
|
|
137
137
|
|
|
138
138
|
## Single-instance behavior
|
|
139
139
|
|
|
@@ -141,7 +141,7 @@ Every dispatch is held until `manager.initialize()` completes (main.js calls `de
|
|
|
141
141
|
|
|
142
142
|
1. The new instance loses the lock.
|
|
143
143
|
2. The OS forwards its argv to the original instance.
|
|
144
|
-
3. The new instance's `
|
|
144
|
+
3. The new instance's `omega.initialize()` halts (after `protocol.hasSingleInstanceLock() === false`): the duplicate quits and its promise never settles.
|
|
145
145
|
4. The original instance's `app.on('second-instance')` fires with the Chromium-processed argv as its second argument AND the duplicate's real argv as its fourth, `additionalData` (@omega.js/desktop passes `{ argv, cwd }` to `app.requestSingleInstanceLock()` for you).
|
|
146
146
|
5. @omega.js/desktop extracts the deep-link URL from that argv and dispatches normally — but as `source: 'warm-start'`.
|
|
147
147
|
6. @omega.js/desktop also focuses the existing main window automatically (consumer can override by registering a route handler that does its own thing).
|
|
@@ -156,10 +156,10 @@ Never parse the event's own `argv` for flags: Chromium re-serializes it (switche
|
|
|
156
156
|
|
|
157
157
|
## Linking with `appState`
|
|
158
158
|
|
|
159
|
-
When a deep link is detected at cold-start, @omega.js/desktop calls `
|
|
159
|
+
When a deep link is detected at cold-start, @omega.js/desktop calls `omega.appState.setLaunchedFromDeepLink(true)`. This means:
|
|
160
160
|
|
|
161
161
|
```js
|
|
162
|
-
if (
|
|
162
|
+
if (omega.appState.launchedFromDeepLink()) {
|
|
163
163
|
// user clicked a link to launch the app — handle differently than a tray click or login launch
|
|
164
164
|
}
|
|
165
165
|
```
|
|
@@ -171,7 +171,7 @@ Combine with `appState.isFirstLaunch()` to detect "first launch via deep link" (
|
|
|
171
171
|
The dispatch pipeline is unit-testable without actually triggering an OS event:
|
|
172
172
|
|
|
173
173
|
```js
|
|
174
|
-
|
|
174
|
+
omega.deepLink.dispatch('myapp://auth/token?token=test');
|
|
175
175
|
// Fires source='manual'. Handlers run synchronously.
|
|
176
176
|
```
|
|
177
177
|
|
|
@@ -180,7 +180,7 @@ See `src/test/suites/main/deep-link.test.js` for the full coverage.
|
|
|
180
180
|
## Implementation notes
|
|
181
181
|
|
|
182
182
|
- `lib/protocol.js` owns the single-instance lock + scheme registration; `lib/deep-link.js` owns the dispatch pipeline. They're separate modules but tightly coupled.
|
|
183
|
-
- OS scheme registration is gated on `
|
|
183
|
+
- OS scheme registration is gated on `omega.isProduction()` (in `lib/protocol.js`): unpackaged dev/test binaries are never registered as system protocol handlers (unconditional registration also intermittently triggered macOS Launch Services `-600` dialogs during test runs).
|
|
184
184
|
- On Windows/Linux, scheme registration uses `app.setAsDefaultProtocolClient(scheme, process.execPath, [process.cwd()])` so `app.exe scheme://...` style invocations route argv correctly.
|
|
185
185
|
- macOS open-url events that arrive before `whenReady` are queued internally and drained on `deepLink.initialize()`.
|
|
186
186
|
- Argv extraction walks backward from the end of argv (where the URL typically sits) and matches against registered schemes.
|
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
`getEnvironment()` returns exactly ONE of three mutually-exclusive, exhaustive values:
|
|
4
4
|
|
|
5
5
|
```javascript
|
|
6
|
-
|
|
6
|
+
omega.getEnvironment() // 'development' | 'testing' | 'production'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
omega.isDevelopment() // true ONLY in development
|
|
9
|
+
omega.isTesting() // true ONLY in testing
|
|
10
|
+
omega.isProduction() // true ONLY in production
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
**ONE input, and no default** ([#817](https://github.com/Omega-JS-Stack/omega/issues/817)). `getEnvironment()` reads the `OMEGA_ENVIRONMENT` variable in Node, and the baked `OMEGA_BUILD_JSON.config.environment` in a renderer (which has no `process.env`). Nothing else is consulted: the `app.isPackaged`, `config.em.environment`, `OMEGA_BUILD_MODE` and `NODE_ENV` sniffs are gone, and a context with neither input **throws**, naming the variable. The old default here was `production`, so a plain `npm start` bundled itself as a production artifact while @omega.js/extension's copy of the same function answered `development` from the same inputs.
|
|
14
14
|
|
|
15
|
-
**One implementation, shared with every sibling framework.** The four calls are `@omega.js/config`'s [environment.js](../../config/src/environment.js), the module @omega.js/extension, @omega.js/web, @omega.js/backend and @omega.js/client all answer from. @omega.js/desktop has four
|
|
15
|
+
**One implementation, shared with every sibling framework.** The four calls are `@omega.js/config`'s [environment.js](../../config/src/environment.js), the module @omega.js/extension, @omega.js/web, @omega.js/backend and @omega.js/client all answer from. @omega.js/desktop has four entry points (main / renderer / preload / build); [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) re-exports the shared four beside desktop's own `getVersion()`. The build module exports them as plain functions, and every process's `omega` carries them as methods.
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
omega.getEnvironment() // same answer in main / renderer / preload
|
|
19
|
+
require('@omega.js/desktop/build').isTesting() // the build module, for build-time scripts
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
**Who sets the input.** [src/build.js](../src/build.js) names it at LOAD, from the lane: `OMEGA_BUILD_MODE` (which `omega build` / `package` / `publish` / `release` and the boot runner's staged build all set) is `production` and WINS over an inherited value, so a production build spawned from a test run still bakes production; otherwise a lane that already named one keeps it (the test runners spawn their children naming `testing`), and a bare dev boot is `development`. The electron app that lane spawns inherits the variable. A PACKAGED app has no parent lane, so [src/main.js](../src/main.js) names it from the word the build baked into the artifact: that is a FALLBACK for the context with no input, never an override ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)). A process that already carries `OMEGA_ENVIRONMENT` keeps it, which is why a test lane that boots a production artifact still answers `testing` inside it.
|
|
23
23
|
|
|
24
|
-
**The renderer gets the running word too.** A page has no `process`, so its
|
|
24
|
+
**The renderer gets the running word too.** A page has no `process`, so its `omega` reads input 2, the baked `config.environment`, which is the word the BUILD was for. Those agree everywhere except a lane that boots a production artifact, so the preload (a Node context, it has the variable) exposes it on `window.desktop.environment` and [src/renderer.js](../src/renderer.js) applies it over the baked word at `initialize()`. Same precedence, one context removed: the running environment first, the bake second. No second signal exists.
|
|
25
25
|
|
|
26
26
|
**The three checks are mutually exclusive**: exactly one is true. `isDevelopment()` is **false** during testing, and `isProduction()` is a real positive check (it is NOT `!isDevelopment()`).
|
|
27
27
|
|
|
@@ -52,14 +52,14 @@ if (isDevelopment() || isTesting()) { /* localhost URL, isolate userData, suppre
|
|
|
52
52
|
## URL helpers
|
|
53
53
|
|
|
54
54
|
```javascript
|
|
55
|
-
|
|
55
|
+
omega.getApiUrl() // the app's API URL: the SSOT for calling the backend
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
`getApiUrl()` / `getFunctionsUrl()` / `getWebsiteUrl()` resolve to **local** URLs (from the baked dev map, whose floor is the classic hosting / functions / website numbers) in development OR testing, and to production (`https://api.<brand.url host>` etc.) otherwise. They route through `this.getEnvironment()`, so they're correct everywhere without an argument: call them directly. Pass an explicit `env` arg (`getApiUrl('production')`) only to force a specific environment regardless of the current one, rarely needed, and mainly used by tests to pin a specific environment's mapping.
|
|
59
59
|
|
|
60
|
-
`getAuthUrl()` builds the **sign-in URL that round-trips an auth token back to the app**: `<site>/signin?authReturnUrl=<site>/token?authReturnUrl=<brand.id>://auth/token`, where `<site>` is `getWebsiteUrl()` (same env split). The
|
|
60
|
+
`getAuthUrl()` builds the **sign-in URL that round-trips an auth token back to the app**: `<site>/signin?authReturnUrl=<site>/token?authReturnUrl=<brand.id>://auth/token`, where `<site>` is `getWebsiteUrl()` (same env split). The website's `/signin` page logs the user in (or bounces straight through if already signed in), its `/token` page mints a Firebase custom token via the backend, and the final redirect (`?authToken=<token>`, the ONE shape) deep-links the token into the app's built-in `auth/token` route → `omega.auth.handleToken()` → `signInWithCustomToken`. Use it for EVERY "Sign in" affordance an app exposes; never link the bare `/signin` page, which strands the login in the browser. Requires `brand.id` (the deep-link scheme) in config; throws when missing. The optional second arg `getAuthUrl(env, returnUrl)` overrides the chain's final hop: that's how `lib/auth-flow.js` swaps in its dev loopback return.
|
|
61
61
|
|
|
62
|
-
**Apps should launch the flow through `
|
|
62
|
+
**Apps should launch the flow through `omega.openAuthFlow()` (main process), not by opening `getAuthUrl()` themselves**: production opens `getAuthUrl()` externally as-is (the OS routes the custom scheme back), while dev/test, where the scheme is NOT OS-registered (protocol.js registers only in production, and macOS can't runtime-register schemes missing from the bundle's Info.plist), swap the final hop for a one-shot, nonce-checked loopback HTTP listener (RFC 8252 §7.3) that feeds the token into the SAME deep-link pipeline. Sign-in always happens in the user's REAL default browser (their existing session/SSO), never an embedded window. Requires @omega.js/client ≥ 4.3.4 on the website (`isValidRedirectUrl` accepts loopback hosts while the SITE runs in dev). See [src/lib/auth-flow.js](../src/lib/auth-flow.js).
|
|
63
63
|
|
|
64
64
|
All three local helpers resolve from whichever channel the process has: the `OMEGA_*_PORT` env vars (the CLI that booted the stack publishes them), then the `dev` map the bundle baked into `OMEGA_BUILD_JSON` (a packaged main process has no parent env, so a bumped emulator port reaches it only this way, [#745](https://github.com/Omega-JS-Stack/omega/issues/745)). There is no third step: the classic numbers used to be hand-typed under them, and they are gone ([#834](https://github.com/Omega-JS-Stack/omega/issues/834)).
|
|
65
65
|
|
|
@@ -73,15 +73,15 @@ The classics still reach these helpers, from the ONE place they are defined: the
|
|
|
73
73
|
|
|
74
74
|
The first two rows are port chains: each cell names a port, and the helper builds the URL around it. The website row is an ORIGIN chain ([#747](https://github.com/Omega-JS-Stack/omega/issues/747)): the baked `dev.origin` the live website published carries scheme, host AND port, so it is the complete fact and outranks the port cell; only when it is absent does a port compose an origin, over **https**, because `omega dev` fronts its public port with the mkcert proxy by default and a port number alone can never say the scheme. Whenever the website published an origin, that is the same answer `@omega.js/client`'s `getDevWebsiteOrigin()` gives every other surface ([#262](https://github.com/Omega-JS-Stack/omega/issues/262)), and `getAuthUrl()` inherits it by construction.
|
|
75
75
|
|
|
76
|
-
A resolved `OMEGA_HTTPS_PORT` (or a baked `dev.ports.https`) means `omega serve`'s mkcert proxy is up, so the api URL is https. That is the same chain @omega.js/extension's `getApiUrl()` walks, and the same one
|
|
76
|
+
A resolved `OMEGA_HTTPS_PORT` (or a baked `dev.ports.https`) means `omega serve`'s mkcert proxy is up, so the api URL is https. That is the same chain @omega.js/extension's `getApiUrl()` walks, and the same one `omega.auth` uses for the auth emulator port (`OMEGA_AUTH_PORT` → `dev.ports.auth` → throw, [auth.md](auth.md)).
|
|
77
77
|
|
|
78
78
|
Resolving local in test mode is required because tests hit the local emulator — without it, the app (and tests calling `getApiUrl()`) would leak to the live production server.
|
|
79
79
|
|
|
80
|
-
> The URL helpers live in [src/utils/url-helpers.js](../src/utils/url-helpers.js)
|
|
80
|
+
> The URL helpers live in [src/utils/url-helpers.js](../src/utils/url-helpers.js) as plain functions of the instance (`getApiUrl(omega, environment)`), reading its `getEnvironment()`; each process class calls them from its own methods.
|
|
81
81
|
|
|
82
82
|
## Where they live
|
|
83
83
|
|
|
84
|
-
Source: [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) for `getEnvironment()` + `is*()` + `getVersion()`; [src/utils/url-helpers.js](../src/utils/url-helpers.js) for the URL builders.
|
|
84
|
+
Source: [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) for `getEnvironment()` + `is*()` + `getVersion()`; [src/utils/url-helpers.js](../src/utils/url-helpers.js) for the URL builders. Both modules export plain functions. [build.js](../src/build.js) exports the mode helpers as they are; the three process classes, [main.js](../src/main.js) (the methods mixed in from [lib/_environment-mixin.js](../src/lib/_environment-mixin.js)), [preload.js](../src/preload.js) and [renderer.js](../src/renderer.js), call them from their own methods (the renderer takes the environment four and `getApiUrl()` / `getFunctionsUrl()` from @omega.js/client's base class it extends).
|
|
85
85
|
|
|
86
86
|
## How detection works
|
|
87
87
|
|
|
@@ -89,7 +89,7 @@ Source: [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) for `getEnviro
|
|
|
89
89
|
([#817](https://github.com/Omega-JS-Stack/omega/issues/817)):
|
|
90
90
|
|
|
91
91
|
1. **`process.env.OMEGA_ENVIRONMENT`**, wherever this context has a `process` (main, preload, build-time Node).
|
|
92
|
-
2. **The baked `config.environment`** off the
|
|
92
|
+
2. **The baked `config.environment`** off the `omega` the call is made on, for a renderer, which has none. It is the build fact every OMEGA surface spells the same way ([#896](https://github.com/Omega-JS-Stack/omega/issues/896)). The preload hands the running word across to the renderer when the two differ, so this step answers the artifact's own build only when no lane named one ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)).
|
|
93
93
|
3. **Neither** is a loud error naming `OMEGA_ENVIRONMENT`. There is no default, because the four framework copies this replaced each had one and they disagreed.
|
|
94
94
|
|
|
95
95
|
The lanes above supply that input, and the whole table of who names what lives in
|
|
@@ -97,7 +97,7 @@ The lanes above supply that input, and the whole table of who names what lives i
|
|
|
97
97
|
|
|
98
98
|
## Adding a new helper
|
|
99
99
|
|
|
100
|
-
Write the function in a `src/utils/<topic>-helpers.js` module,
|
|
100
|
+
Write the function in a `src/utils/<topic>-helpers.js` module, export it from [build.js](../src/build.js), and call it from a method on each process class that needs it. Don't define a helper's logic inside one process class: that path leads to duplicated semantics. For anything environment-derived, derive from `getEnvironment()` rather than reading `process.env` / `app.*` directly, so there is one source of truth and no chance of drift.
|
|
101
101
|
|
|
102
102
|
## Why this matters
|
|
103
103
|
|
package/docs/fontawesome.md
CHANGED
|
@@ -35,7 +35,7 @@ drift on how an icon name resolves or what the served SVG looks like.
|
|
|
35
35
|
`metadata/icon-families.json` for aliases (`search` → `magnifying-glass`).
|
|
36
36
|
Declared dependencies ride into packaged apps automatically (fs reads
|
|
37
37
|
through the asar transparently).
|
|
38
|
-
- **Main lib** (`lib/fontawesome.js`)
|
|
38
|
+
- **Main lib** (`lib/fontawesome.js`): `omega.fontawesome.get(name, style)`
|
|
39
39
|
resolves an icon to its SVG string (`null` for unknown names — never
|
|
40
40
|
throws). Lookups are slug-sanitized via icon-core (the IPC channel can
|
|
41
41
|
never read outside the icon directories) and cached per app run. Serves
|
|
@@ -61,11 +61,13 @@ drift on how an icon name resolves or what the served SVG looks like.
|
|
|
61
61
|
## Minimal surfaces
|
|
62
62
|
|
|
63
63
|
The auto-render is wired by `initialize()`. A renderer that deliberately skips
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
`initialize()` (e.g. a lightweight popover overlay with no auth) can enable JUST
|
|
65
|
+
the icon pipeline on the same instance:
|
|
66
66
|
|
|
67
67
|
```js
|
|
68
|
-
|
|
68
|
+
import omega from '@omega.js/desktop/renderer';
|
|
69
|
+
|
|
70
|
+
omega.enableFontAwesome();
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
## Supplying Font Awesome Pro (C4 cp111)
|
|
@@ -88,7 +90,7 @@ own **prod dependency** so the set ships inside the asar.
|
|
|
88
90
|
`window.desktop.fontawesome.get()` and swap yourself.
|
|
89
91
|
- **Free set = solid + regular + brands.** Pro styles (light/duotone/sharp)
|
|
90
92
|
need a supplied Pro set (above); otherwise
|
|
91
|
-
`
|
|
93
|
+
`omega.fontawesome.get(name, 'duotone')` returns `null`.
|
|
92
94
|
- **Updating the set** — bump the `@fortawesome/fontawesome-free` dependency
|
|
93
95
|
(or reinstall/refresh the brand's Pro supply).
|
|
94
96
|
|
package/docs/hooks.md
CHANGED
|
@@ -6,7 +6,7 @@ Consumers can inject custom logic at well-defined points without forking @omega.
|
|
|
6
6
|
|
|
7
7
|
1. @omega.js/desktop scaffolds empty hook files into `<consumer>/hooks/**/*.js` on every verb (`ensureTarget()`).
|
|
8
8
|
2. At each lifecycle point, @omega.js/desktop checks for the file. If it exists, @omega.js/desktop loads + invokes it. If not, no-op.
|
|
9
|
-
3. The hook signature is `async (ctx) => { ... }
|
|
9
|
+
3. The hook signature is `async (ctx) => { ... }`, with `ctx` the ONE hook-argument shape every OMEGA framework passes, `{ build, projectRoot, mode }`: `build` is the build module (`require('@omega.js/desktop/build')`, one plain object of functions: `getConfig()`, `getPackage()`, `getRootPath()`, ...). Whatever it returns is awaited but ignored.
|
|
10
10
|
4. **Failure semantics:**
|
|
11
11
|
- File missing entirely → logged informationally (`hook "<name>" not present at ... — skipping.`), build continues.
|
|
12
12
|
- File exists but fails to load (syntax error, etc.) → **throws**, build fails.
|
|
@@ -19,11 +19,11 @@ Consumers can inject custom logic at well-defined points without forking @omega.
|
|
|
19
19
|
|
|
20
20
|
| Hook file | When it runs | `ctx` shape |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| `hooks/build/pre.js` | Before the build pipeline runs (`defaults` → `distribute` → `bundle` ...) | `{
|
|
23
|
-
| `hooks/build/post.js` | After the build pipeline finishes, before `electron-builder` packages anything | `{
|
|
24
|
-
| `hooks/release/pre.js` | Before `electron-builder build --publish always` | `{
|
|
25
|
-
| `hooks/release/post.js` | After the release publishes | `{
|
|
26
|
-
| `hooks/deploy/pre.js` | Inside `omega deploy`, after the local scaffold and before the network precheck, on both lanes (the dispatch and `--direct`); a dry run skips it, because a hook may act on the world ([#900](https://github.com/Omega-JS-Stack/omega/issues/900): the playground's prunes its release family down to the newest, so two releases stay live; the VERSION comes from `omega bump` at the brand root, [#869](https://github.com/Omega-JS-Stack/omega/issues/869), never from a hook) | `{
|
|
22
|
+
| `hooks/build/pre.js` | Before the build pipeline runs (`defaults` → `distribute` → `bundle` ...) | `{ build, projectRoot, mode }` |
|
|
23
|
+
| `hooks/build/post.js` | After the build pipeline finishes, before `electron-builder` packages anything | `{ build, projectRoot, mode }` |
|
|
24
|
+
| `hooks/release/pre.js` | Before `electron-builder build --publish always` | `{ build, projectRoot, mode }` |
|
|
25
|
+
| `hooks/release/post.js` | After the release publishes | `{ build, projectRoot, mode }` |
|
|
26
|
+
| `hooks/deploy/pre.js` | Inside `omega deploy`, after the local scaffold and before the network precheck, on both lanes (the dispatch and `--direct`); a dry run skips it, because a hook may act on the world ([#900](https://github.com/Omega-JS-Stack/omega/issues/900): the playground's prunes its release family down to the newest, so two releases stay live; the VERSION comes from `omega bump` at the brand root, [#869](https://github.com/Omega-JS-Stack/omega/issues/869), never from a hook) | `{ build, projectRoot, mode: 'production' }` |
|
|
27
27
|
| `hooks/notarize/post.js` | After @omega.js/desktop's built-in macOS notarization completes (extension only — @omega.js/desktop's notarize is the real entrypoint) | electron-builder afterSign context |
|
|
28
28
|
|
|
29
29
|
`mode` is `'production'` when `OMEGA_BUILD_MODE=true`, else `'development'`. A deploy hook always reads `'production'`: the verb runs outside a build, and what it is about to publish is a release.
|
|
@@ -32,7 +32,7 @@ Consumers can inject custom logic at well-defined points without forking @omega.
|
|
|
32
32
|
|
|
33
33
|
- **Notarize specifically:** the consumer's `hooks/notarize/post.js` is **never** the electron-builder afterSign entrypoint. @omega.js/desktop's `gulp/build-config` injects `afterSign:` pointing at @omega.js/desktop's real notarize implementation (resolved via `require.resolve('@omega.js/desktop/hooks/notarize')`). @omega.js/desktop's real notarize calls into the consumer's `hooks/notarize/post.js` as a final post-step. So the consumer can never accidentally break notarization by editing the file — the file can be empty, malformed, or missing entirely and the app still notarizes correctly.
|
|
34
34
|
- **Why no `hooks/notarize/pre.js`?** electron-builder's `afterSign` hook is the only signing-related extension point we control. Anything that would belong in a "pre-notarize" step belongs either in `hooks/release/pre.js` (whole-release-level prep, runs before the gulp release task), or in electron-builder's own `afterPack` / `afterAllArtifactBuild` configuration (per-artifact mutation). If you have a real use case that doesn't fit either, file an issue.
|
|
35
|
-
- **Build/release hooks:** standard before/after lifecycle pattern
|
|
35
|
+
- **Build/release hooks:** standard before/after lifecycle pattern, the same `ctx` @omega.js/extension hands its hooks.
|
|
36
36
|
|
|
37
37
|
## Examples
|
|
38
38
|
|
|
@@ -40,7 +40,7 @@ Consumers can inject custom logic at well-defined points without forking @omega.
|
|
|
40
40
|
|
|
41
41
|
```js
|
|
42
42
|
// hooks/release/post.js
|
|
43
|
-
module.exports = async ({
|
|
43
|
+
module.exports = async ({ build, projectRoot }) => {
|
|
44
44
|
const pkg = require(`${projectRoot}/package.json`);
|
|
45
45
|
const url = process.env.SLACK_WEBHOOK_URL;
|
|
46
46
|
if (!url) return;
|