@omega.js/desktop 0.52.0 → 0.54.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 +53 -48
- 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-run.js +4 -1
- package/dist/cli.js +3 -3
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- 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/cdp.js +1 -1
- package/dist/commands/clean.js +4 -5
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/dev.js +25 -0
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +18 -23
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +4 -4
- package/dist/commands/runner.js +11 -11
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +8 -8
- package/dist/commands/update.js +7 -6
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +18 -18
- package/dist/defaults/_.gitignore +0 -2
- package/dist/defaults/_mas/README.md +3 -3
- package/dist/defaults/config/certs/README.md +1 -1
- package/dist/defaults/config/omega.json5 +43 -43
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +2 -2
- package/dist/defaults/hooks/build/pre.js +2 -2
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +2 -2
- package/dist/defaults/hooks/release/pre.js +2 -2
- 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/assets/scss/pages/about.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
- package/dist/defaults/src/integrations/context-menu/index.js +13 -13
- package/dist/defaults/src/integrations/menu/index.js +8 -8
- package/dist/defaults/src/integrations/tray/index.js +12 -12
- package/dist/defaults/src/main.js +5 -7
- package/dist/defaults/src/preload.js +4 -6
- package/dist/defaults/test/README.md +5 -5
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +11 -14
- 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 +29 -29
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- 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 +399 -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 +21 -8
- 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/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +30 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +21 -7
- package/dist/test/suites/build/deploy-direct.test.js +7 -5
- package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
- package/dist/test/suites/build/deploy-hook.test.js +7 -5
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +13 -5
- 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 +7 -7
- package/dist/test/suites/build/migrate.test.js +29 -0
- 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/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +11 -10
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- 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 +15 -4
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- 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} +28 -8
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/runner-env.js +13 -28
- 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/company.js +46 -14
- package/dist/vendor/config/defaults.js +30 -7
- package/dist/vendor/config/edit.js +25 -3
- package/dist/vendor/config/env-delivery.js +1 -1
- package/dist/vendor/config/env-schema.js +3 -6
- package/dist/vendor/config/env.js +34 -22
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +21 -28
- package/dist/vendor/config/load.js +16 -9
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +10 -27
- package/dist/vendor/config/schema-client.js +64 -0
- package/dist/vendor/config/schema-cloud.js +38 -0
- package/dist/vendor/config/schema-manager.js +118 -0
- package/dist/vendor/config/schema-overrides.js +68 -0
- package/dist/vendor/config/schema.js +104 -160
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +97 -78
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +16 -2
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +16 -11
- package/dist/vendor/devkit/defaults-engine.js +15 -51
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +64 -10
- package/dist/vendor/devkit/lockfile.js +32 -13
- package/dist/vendor/devkit/logger.js +7 -2
- package/dist/vendor/devkit/merge-line-files.js +219 -177
- package/dist/vendor/devkit/omega-bin.js +208 -111
- package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
- package/dist/vendor/devkit/preludes/index.js +1 -0
- package/dist/vendor/devkit/target-picker.js +45 -0
- package/dist/vendor/devkit/test/dashed-files.js +37 -0
- package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/devkit/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- 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/package.json +19 -26
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -110
- package/dist/defaults/CLAUDE.md +0 -1
- 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/dist/vendor/config/env-retired.js +0 -137
- package/dist/vendor/config/retired-keys.js +0 -635
- package/docs/analytics.md +0 -140
- package/docs/app-state.md +0 -92
- package/docs/audit.md +0 -69
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -39
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- package/docs/client-bridge.md +0 -269
- package/docs/common-mistakes.md +0 -21
- package/docs/config-schema.md +0 -120
- package/docs/context-menu.md +0 -112
- package/docs/context.md +0 -81
- package/docs/css.md +0 -90
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -107
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -317
- package/docs/installer-options.md +0 -165
- package/docs/ipc.md +0 -61
- package/docs/lib-modules.md +0 -53
- package/docs/logging.md +0 -229
- package/docs/menu.md +0 -160
- package/docs/releasing.md +0 -239
- package/docs/remote-config.md +0 -118
- package/docs/remote-scripts.md +0 -144
- package/docs/restart-manager.md +0 -144
- package/docs/runner.md +0 -290
- package/docs/sentry.md +0 -97
- package/docs/shared/agent-docs.md +0 -89
- package/docs/shared/analytics.md +0 -612
- package/docs/shared/brands.md +0 -57
- package/docs/shared/breaking-changes.md +0 -851
- package/docs/shared/config.md +0 -1952
- package/docs/shared/deploys.md +0 -341
- package/docs/shared/icons.md +0 -219
- package/docs/shared/local-dev.md +0 -167
- package/docs/shared/logging.md +0 -205
- package/docs/shared/monitoring.md +0 -167
- package/docs/shared/publishing.md +0 -187
- package/docs/shared/rulings.md +0 -34
- package/docs/shared/testing.md +0 -147
- package/docs/shared/theming.md +0 -629
- package/docs/shared/translation.md +0 -333
- package/docs/shared/updates.md +0 -61
- package/docs/signing.md +0 -293
- package/docs/startup.md +0 -142
- package/docs/storage.md +0 -59
- package/docs/templating.md +0 -101
- package/docs/test-boot-layer.md +0 -157
- package/docs/test-framework.md +0 -362
- package/docs/themes.md +0 -149
- package/docs/tooltips.md +0 -99
- package/docs/tray.md +0 -164
- package/docs/usage.md +0 -58
- package/docs/verts.md +0 -62
- package/docs/windows.md +0 -149
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// The main process's quit/relaunch pair: methods mixed into the `Omega` class
|
|
2
|
+
// (src/main.js) with `Object.assign(Omega.prototype, ...)`, so they stay
|
|
3
|
+
// `omega.quit()` and `omega.relaunch()` on the instance.
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
// Force a real quit, bypassing per-window `hideOnClose`. Use this anywhere the
|
|
7
|
+
// app legitimately wants to exit (tray Quit, Cmd+Q from menu role:'quit',
|
|
8
|
+
// auto-updater install). Without `{ force: true }`, the close events still get
|
|
9
|
+
// trapped by hide-on-close handlers and the app stays running.
|
|
10
|
+
quit(options) {
|
|
11
|
+
options = options || {};
|
|
12
|
+
|
|
13
|
+
if (options.force) {
|
|
14
|
+
this._allowQuit = true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
require('electron').app.quit();
|
|
19
|
+
} catch (e) { /* electron not available: no-op in test/headless */ }
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// Force a relaunch: same gating as quit, but tells electron to start back up
|
|
23
|
+
// after exit. If an update has been downloaded, prefers `quitAndInstall()` so
|
|
24
|
+
// the user lands on the new version instead of the old one.
|
|
25
|
+
relaunch(options) {
|
|
26
|
+
options = options || {};
|
|
27
|
+
|
|
28
|
+
if (options.force) {
|
|
29
|
+
this._allowQuit = true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const electron = require('electron');
|
|
33
|
+
|
|
34
|
+
// If updater downloaded a fresh build, install + relaunch via electron-updater
|
|
35
|
+
// (which calls `app.quit()` internally with the right post-quit script). Falls
|
|
36
|
+
// back to plain relaunch if updater hasn't downloaded anything.
|
|
37
|
+
const updaterStatus = this.autoUpdater.getStatus();
|
|
38
|
+
if (updaterStatus.code === 'downloaded') {
|
|
39
|
+
return this.autoUpdater.installNow();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
electron.app.relaunch();
|
|
43
|
+
electron.app.quit();
|
|
44
|
+
},
|
|
45
|
+
};
|
package/dist/lib/analytics.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Analytics — GA4 via Measurement Protocol. Mirrors @omega.js/backend's
|
|
2
|
-
// `
|
|
3
|
-
// tracked across desktop (@omega.js/desktop) + web (
|
|
2
|
+
// `omega.config.analytics.providers.google.id` shape so the same person can be
|
|
3
|
+
// tracked across desktop (@omega.js/desktop) + web (@omega.js/client) + backend (@omega.js/backend) by
|
|
4
4
|
// referencing a single namespaced UUIDv5 identity.
|
|
5
5
|
//
|
|
6
6
|
// Cross-platform identity (the key feature):
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
// namespace via uuidv5.URL of the projectId string. Same projectId in @omega.js/backend/@omega.js/client/@omega.js/desktop
|
|
19
19
|
// → the same uid hashes to the same user_id everywhere → unified analytics.
|
|
20
20
|
//
|
|
21
|
-
// Anonymous (
|
|
21
|
+
// Anonymous (auth holds no signed-in account yet) → user_id stays null.
|
|
22
22
|
// Authed (auth event fires) → user_id is set + a `login` event is dispatched. On
|
|
23
23
|
// logout → user_id clears + `logout` event fires.
|
|
24
24
|
//
|
|
25
25
|
// API surface:
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
26
|
+
// omega.analytics.event(name, params?) // generic event
|
|
27
|
+
// omega.analytics.pageview(path?) // convenience wrapper
|
|
28
|
+
// omega.analytics.screenview(name?) // convenience wrapper
|
|
29
|
+
// omega.analytics.setUserId(uid) // manual override; auto-wired to auth
|
|
30
|
+
// omega.analytics.setUserProperties(props) // merge into user_properties block
|
|
31
31
|
//
|
|
32
32
|
// Events fired during normal operation are queued until init completes (we need
|
|
33
33
|
// context.session + measurement_id + secret). Once initialized, the queue
|
|
@@ -67,7 +67,7 @@ const MAX_QUEUE = 200;
|
|
|
67
67
|
|
|
68
68
|
const analytics = {
|
|
69
69
|
_initialized: false,
|
|
70
|
-
|
|
70
|
+
_omega: null,
|
|
71
71
|
_enabled: false,
|
|
72
72
|
_measurementId: null,
|
|
73
73
|
_apiSecret: null,
|
|
@@ -78,12 +78,12 @@ const analytics = {
|
|
|
78
78
|
_queue: [],
|
|
79
79
|
_authUnsub: null,
|
|
80
80
|
|
|
81
|
-
initialize(
|
|
81
|
+
initialize(omega) {
|
|
82
82
|
if (analytics._initialized) return;
|
|
83
83
|
analytics._initialized = true;
|
|
84
|
-
analytics.
|
|
84
|
+
analytics._omega = omega;
|
|
85
85
|
|
|
86
|
-
const cfg =
|
|
86
|
+
const cfg = omega.config.analytics || {};
|
|
87
87
|
|
|
88
88
|
// Presence-driven: providers.google.id presence enables analytics. No separate
|
|
89
89
|
// `enabled` flag (matches @omega.js/backend convention — credentials are the enable signal).
|
|
@@ -109,8 +109,8 @@ const analytics = {
|
|
|
109
109
|
// projectId in @omega.js/backend/@omega.js/client/@omega.js/desktop → same namespace → same per-uid UUIDv5
|
|
110
110
|
// everywhere. UUIDv5 needs a UUID-shaped namespace — we derive one from the
|
|
111
111
|
// string projectId by hashing it into uuidv5.URL space (RFC 4122).
|
|
112
|
-
const projectId =
|
|
113
|
-
||
|
|
112
|
+
const projectId = omega.config.cloud?.config?.projectId
|
|
113
|
+
|| omega.config.brand.id;
|
|
114
114
|
analytics._namespace = core.deriveNamespace(projectId);
|
|
115
115
|
|
|
116
116
|
// Apply a uid stored by a pre-init setUserId() call — the auth
|
|
@@ -125,7 +125,7 @@ const analytics = {
|
|
|
125
125
|
// so an empty one is a broken boot order, never a runtime condition — and a
|
|
126
126
|
// fresh id minted here would persist nowhere, making every launch a new GA
|
|
127
127
|
// client (#396). It raises instead.
|
|
128
|
-
const deviceId =
|
|
128
|
+
const deviceId = omega.context.session.deviceId;
|
|
129
129
|
|
|
130
130
|
if (!deviceId) {
|
|
131
131
|
throw new Error('analytics.initialize() ran before context.initialize() resolved session.deviceId — the boot sequence must init context first');
|
|
@@ -142,16 +142,14 @@ const analytics = {
|
|
|
142
142
|
analytics_.configure({
|
|
143
143
|
transport: { send: (descriptor) => analytics._send(descriptor) },
|
|
144
144
|
context: { runtime: 'electron' },
|
|
145
|
-
environment:
|
|
145
|
+
environment: omega.isDevelopment?.() ? 'development' : 'production',
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
// Listen to auth so user_id flips automatically on login/logout. The listen
|
|
149
|
+
// catch-up delivers the state auth already holds, so nothing is pulled here.
|
|
150
|
+
analytics._authUnsub = omega.auth.listen(({ user }) => {
|
|
151
|
+
analytics._handleAuthChange(user);
|
|
151
152
|
});
|
|
152
|
-
// Pull current state immediately in case auth already resolved.
|
|
153
|
-
const current = manager.omega.getCurrentUser();
|
|
154
|
-
if (current?.uid) analytics._handleAuthChange(current);
|
|
155
153
|
|
|
156
154
|
// Compute initial user_properties from context + usage.
|
|
157
155
|
analytics._userProperties = analytics._buildUserProperties();
|
|
@@ -176,11 +174,11 @@ const analytics = {
|
|
|
176
174
|
|
|
177
175
|
// IPC: renderer → main analytics calls. Forward fires-and-forgets via send;
|
|
178
176
|
// status query via invoke.
|
|
179
|
-
|
|
180
|
-
|
|
177
|
+
omega.ipc.unhandle('desktop:analytics:status');
|
|
178
|
+
omega.ipc.handle('desktop:analytics:status', () => analytics.toJSON());
|
|
181
179
|
// Use Set-deduped listener; named handler so re-init collapses duplicates.
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
omega.ipc.on('desktop:analytics:event', analytics._onIpcEvent);
|
|
181
|
+
omega.ipc.on('desktop:analytics:set-user-properties', analytics._onIpcSetProps);
|
|
184
182
|
},
|
|
185
183
|
|
|
186
184
|
_onIpcEvent({ name, params } = {}) {
|
|
@@ -248,7 +246,7 @@ const analytics = {
|
|
|
248
246
|
analytics.event('screen_view', name ? { screen_name: name } : {});
|
|
249
247
|
},
|
|
250
248
|
|
|
251
|
-
// Manual user-id override. Normally
|
|
249
|
+
// Manual user-id override. Normally auth.listen wires this automatically.
|
|
252
250
|
setUserId(uid) {
|
|
253
251
|
if (!analytics._namespace) {
|
|
254
252
|
// Init hasn't run yet — store and apply at init.
|
|
@@ -273,24 +271,24 @@ const analytics = {
|
|
|
273
271
|
// GA4 param contract: each event needs engagement_time_msec (else session bounces),
|
|
274
272
|
// and we add session_id + page_location so reports group properly.
|
|
275
273
|
_enrichParams(params) {
|
|
276
|
-
const
|
|
277
|
-
const ctx =
|
|
274
|
+
const omega = analytics._omega;
|
|
275
|
+
const ctx = omega.context;
|
|
278
276
|
const sessionStart = ctx.session.startTime ? new Date(ctx.session.startTime).getTime() : Date.now();
|
|
279
277
|
const engagement = Math.max(1, Date.now() - sessionStart);
|
|
280
278
|
return {
|
|
281
279
|
session_id: ctx.session.id || 'unknown',
|
|
282
280
|
engagement_time_msec: engagement,
|
|
283
|
-
page_location: params.page_location || `app://${
|
|
284
|
-
page_title: params.page_title ||
|
|
281
|
+
page_location: params.page_location || `app://${omega.config.brand.id}`,
|
|
282
|
+
page_title: params.page_title || omega.config.app?.productName || omega.config.brand.name,
|
|
285
283
|
...params,
|
|
286
284
|
};
|
|
287
285
|
},
|
|
288
286
|
|
|
289
287
|
// Compute user-properties from current context + usage. Re-run on auth change.
|
|
290
288
|
_buildUserProperties() {
|
|
291
|
-
const
|
|
292
|
-
const ctx =
|
|
293
|
-
const usage =
|
|
289
|
+
const omega = analytics._omega;
|
|
290
|
+
const ctx = omega.context;
|
|
291
|
+
const usage = omega.usage;
|
|
294
292
|
const wrap = (v) => ({ value: v });
|
|
295
293
|
const out = {
|
|
296
294
|
app_version: wrap(ctx.app.version || 'unknown'),
|
|
@@ -343,7 +341,7 @@ const analytics = {
|
|
|
343
341
|
analytics._authUnsub();
|
|
344
342
|
}
|
|
345
343
|
analytics._initialized = false;
|
|
346
|
-
analytics.
|
|
344
|
+
analytics._omega = null;
|
|
347
345
|
analytics._enabled = false;
|
|
348
346
|
analytics._measurementId = null;
|
|
349
347
|
analytics._apiSecret = null;
|
package/dist/lib/app-state.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// sentinel: true, // set on launch, cleared on graceful quit; survival = crash
|
|
12
12
|
// }
|
|
13
13
|
//
|
|
14
|
-
// Public API on `
|
|
14
|
+
// Public API on `omega.appState`:
|
|
15
15
|
// isFirstLaunch() — true only for the very first boot of the app on this machine
|
|
16
16
|
// getLaunchCount() — total successful launches (including this one)
|
|
17
17
|
// getInstalledAt() — Date of first launch
|
|
@@ -40,7 +40,7 @@ const STORAGE_KEY = 'appState';
|
|
|
40
40
|
const appState = {
|
|
41
41
|
_initialized: false,
|
|
42
42
|
_quitWired: false,
|
|
43
|
-
|
|
43
|
+
_omega: null,
|
|
44
44
|
_electron: null,
|
|
45
45
|
|
|
46
46
|
// Cached snapshot of the state AS LOADED at the start of this launch.
|
|
@@ -54,15 +54,15 @@ const appState = {
|
|
|
54
54
|
// Set by lib/deep-link.initialize when argv contains a deep-link payload.
|
|
55
55
|
_launchedFromDeepLink: false,
|
|
56
56
|
|
|
57
|
-
async initialize(
|
|
57
|
+
async initialize(omega) {
|
|
58
58
|
if (appState._initialized) {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
appState.
|
|
62
|
+
appState._omega = omega;
|
|
63
63
|
appState._electron = require('electron');
|
|
64
64
|
|
|
65
|
-
const storage =
|
|
65
|
+
const storage = omega.storage;
|
|
66
66
|
|
|
67
67
|
const now = Date.now();
|
|
68
68
|
const previous = storage.get(STORAGE_KEY) || {};
|
|
@@ -74,11 +74,11 @@ const appState = {
|
|
|
74
74
|
const previousQuitAt = previous.lastQuitAt || null;
|
|
75
75
|
appState._recoveredFromCrash = !isFirstLaunch && previousSentinel && !previousQuitAt;
|
|
76
76
|
|
|
77
|
-
// Version detection. Prefer the cross-context
|
|
77
|
+
// Version detection. Prefer the cross-context omega.getVersion() helper —
|
|
78
78
|
// it tries `app.getVersion()` first (authoritative in main, reads asar
|
|
79
79
|
// package.json in packaged builds) and falls back to project package.json.
|
|
80
|
-
const currentVersion =
|
|
81
|
-
||
|
|
80
|
+
const currentVersion = omega.config.app?.version
|
|
81
|
+
|| omega.getVersion()
|
|
82
82
|
|| tryGetVersionFromPackage()
|
|
83
83
|
|| null;
|
|
84
84
|
const previousVersion = previous.version || null;
|
|
@@ -122,7 +122,7 @@ const appState = {
|
|
|
122
122
|
const onQuit = () => {
|
|
123
123
|
if (cleared) return;
|
|
124
124
|
cleared = true;
|
|
125
|
-
const storage = appState.
|
|
125
|
+
const storage = appState._omega.storage;
|
|
126
126
|
const cur = storage.get(STORAGE_KEY) || {};
|
|
127
127
|
cur.sentinel = false;
|
|
128
128
|
cur.lastQuitAt = Date.now();
|
|
@@ -157,7 +157,7 @@ const appState = {
|
|
|
157
157
|
// The CURRENT snapshot's lastQuitAt is null (we cleared it on init).
|
|
158
158
|
// What the consumer wants is "when did we previously quit gracefully" — read storage live,
|
|
159
159
|
// because at the moment of the call this launch hasn't quit yet.
|
|
160
|
-
const cur = appState.
|
|
160
|
+
const cur = appState._omega.storage.get(STORAGE_KEY) || {};
|
|
161
161
|
const ms = cur.lastQuitAt;
|
|
162
162
|
return ms ? new Date(ms) : null;
|
|
163
163
|
},
|
|
@@ -201,7 +201,7 @@ const appState = {
|
|
|
201
201
|
// Test helper — wipe persisted state and reset the in-memory snapshot.
|
|
202
202
|
// (Public, intentionally — used by integration tests + by consumers who want a "reset to factory" command.)
|
|
203
203
|
reset() {
|
|
204
|
-
appState.
|
|
204
|
+
appState._omega.storage.delete(STORAGE_KEY);
|
|
205
205
|
appState._snapshot = null;
|
|
206
206
|
appState._recoveredFromCrash = false;
|
|
207
207
|
appState._launchedFromDeepLink = false;
|
|
@@ -209,11 +209,11 @@ const appState = {
|
|
|
209
209
|
};
|
|
210
210
|
|
|
211
211
|
function tryGetVersionFromPackage() {
|
|
212
|
-
// Last-resort fallback used only when
|
|
212
|
+
// Last-resort fallback used only when omega.getVersion() is unavailable.
|
|
213
213
|
// Reads via build.js's getPackage helper which already handles "no package.json
|
|
214
214
|
// at projectRoot" by returning null — no try/catch needed.
|
|
215
|
-
const
|
|
216
|
-
const pkg =
|
|
215
|
+
const build = require('../build.js');
|
|
216
|
+
const pkg = build.getPackage('project');
|
|
217
217
|
return pkg?.version || null;
|
|
218
218
|
}
|
|
219
219
|
|
package/dist/lib/auth-flow.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Auth Flow — the framework-owned sign-in round trip: `
|
|
1
|
+
// Auth Flow — the framework-owned sign-in round trip: `omega.openAuthFlow()`.
|
|
2
2
|
//
|
|
3
|
-
// Opens the user's REAL default browser on
|
|
3
|
+
// Opens the user's REAL default browser on omega.getAuthUrl()'s /signin → /token
|
|
4
4
|
// chain — never an embedded window, so sign-in rides the user's own browser session
|
|
5
5
|
// (SSO with whatever they're already logged into). What differs per environment is
|
|
6
6
|
// only the RETURN CHANNEL for the minted token:
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
// return), and self-expiring (default 5 min). The browser tab gets a tiny
|
|
26
26
|
// "return to the app" page on success.
|
|
27
27
|
//
|
|
28
|
-
// Public API (via
|
|
29
|
-
//
|
|
28
|
+
// Public API (via omega):
|
|
29
|
+
// omega.openAuthFlow(options?) → Promise<{ url, port? }> — resolves once the flow
|
|
30
30
|
// is LAUNCHED; completion arrives later through
|
|
31
|
-
// auth/token →
|
|
31
|
+
// auth/token → auth.handleToken →
|
|
32
32
|
// the desktop:auth:sign-in-with-token broadcast.
|
|
33
|
-
//
|
|
33
|
+
// omega.authFlow.cancel() → tear down a pending dev listener (idempotent).
|
|
34
34
|
|
|
35
35
|
const crypto = require('crypto');
|
|
36
36
|
const http = require('http');
|
|
@@ -43,26 +43,26 @@ const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
|
43
43
|
|
|
44
44
|
const authFlow = {
|
|
45
45
|
_initialized: false,
|
|
46
|
-
|
|
46
|
+
_omega: null,
|
|
47
47
|
_pending: null, // { server, nonce, timer, port } — the one in-flight dev listener
|
|
48
48
|
|
|
49
|
-
initialize(
|
|
49
|
+
initialize(omega) {
|
|
50
50
|
if (authFlow._initialized) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
authFlow.
|
|
53
|
+
authFlow._omega = omega;
|
|
54
54
|
authFlow._initialized = true;
|
|
55
55
|
},
|
|
56
56
|
|
|
57
57
|
// Open the sign-in flow in the user's default browser. Resolves once the flow is
|
|
58
58
|
// launched — NOT when the user finishes signing in.
|
|
59
59
|
async open(options) {
|
|
60
|
-
const
|
|
60
|
+
const omega = authFlow._omega;
|
|
61
61
|
options = options || {};
|
|
62
62
|
|
|
63
63
|
// Production: the OS routes the custom scheme back to us — plain external open.
|
|
64
|
-
if (
|
|
65
|
-
const url =
|
|
64
|
+
if (omega.isProduction()) {
|
|
65
|
+
const url = omega.getAuthUrl();
|
|
66
66
|
require('electron').shell.openExternal(url);
|
|
67
67
|
logger.log(`production — opened ${url}`);
|
|
68
68
|
return { url };
|
|
@@ -89,7 +89,7 @@ const authFlow = {
|
|
|
89
89
|
authFlow._pending = { server, nonce, timer, port };
|
|
90
90
|
|
|
91
91
|
const returnUrl = `http://127.0.0.1:${port}/auth/token?state=${nonce}`;
|
|
92
|
-
const url =
|
|
92
|
+
const url = omega.getAuthUrl(null, returnUrl);
|
|
93
93
|
require('electron').shell.openExternal(url);
|
|
94
94
|
logger.log(`dev — loopback listener on 127.0.0.1:${port}, opened ${url}`);
|
|
95
95
|
return { url, port };
|
|
@@ -113,7 +113,7 @@ const authFlow = {
|
|
|
113
113
|
},
|
|
114
114
|
|
|
115
115
|
_handleRequest(req, res) {
|
|
116
|
-
const
|
|
116
|
+
const omega = authFlow._omega;
|
|
117
117
|
const pending = authFlow._pending;
|
|
118
118
|
const url = new URL(req.url, 'http://127.0.0.1');
|
|
119
119
|
|
|
@@ -136,18 +136,18 @@ const authFlow = {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// Valid return: reply, tear down, then feed the SAME pipeline production uses.
|
|
139
|
-
const appName =
|
|
139
|
+
const appName = omega.config?.brand?.name || 'the app';
|
|
140
140
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' });
|
|
141
141
|
res.end(authFlow._page('Signed in', `You can close this tab and return to ${appName}.`));
|
|
142
142
|
authFlow.cancel();
|
|
143
143
|
|
|
144
|
-
const brandId =
|
|
145
|
-
|
|
144
|
+
const brandId = omega.config.brand.id;
|
|
145
|
+
omega.deepLink.dispatch(`${brandId}://auth/token?authToken=${encodeURIComponent(token)}`);
|
|
146
146
|
|
|
147
147
|
// The browser held focus during sign-in — bring the app back to the front,
|
|
148
148
|
// mirroring what a real OS deep-link arrival does. windows.show is the
|
|
149
149
|
// stealth-aware surface (raw win.show() would flash windows during tests).
|
|
150
|
-
|
|
150
|
+
omega.windows.show('main');
|
|
151
151
|
},
|
|
152
152
|
|
|
153
153
|
_page(title, message) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Auth Persistence — pluggable MAIN-process storage for the Firebase auth session.
|
|
2
2
|
//
|
|
3
|
-
// Every browser context (renderers here, popup/options/background in
|
|
3
|
+
// Every browser context (renderers here, popup/options/background in an extension) gets Firebase
|
|
4
4
|
// session persistence for free via IndexedDB. Main is the one Node context — Firebase
|
|
5
5
|
// defaults to in-memory there, so sign-in died with the process and the bridge's
|
|
6
6
|
// authority rule signed every renderer out on the next boot.
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
// signal isTestRun() reads below ([#907](https://github.com/Omega-JS-Stack/omega/issues/907)).
|
|
31
31
|
//
|
|
32
32
|
// Select via config `omega.authPersistence` ('safeStorage' | 'none' | a custom
|
|
33
|
-
// registered name). Register custom strategies BEFORE
|
|
33
|
+
// registered name). Register custom strategies BEFORE omega.initialize():
|
|
34
34
|
// require('@omega.js/desktop/lib/auth-persistence').register('keytar', {...})
|
|
35
35
|
//
|
|
36
36
|
// The firebase adapter mirrors firebase's own getReactNativePersistence(): a class
|
|
@@ -114,18 +114,18 @@ const noneStrategy = {
|
|
|
114
114
|
async removeItem() {},
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
-
// Is this process a TEST RUN, in either lane that reaches this lib? The
|
|
117
|
+
// Is this process a TEST RUN, in either lane that reaches this lib? The omega instance
|
|
118
118
|
// answers it, in both: each lane spawns its child with `OMEGA_ENVIRONMENT=testing`
|
|
119
119
|
// and the baked word never writes over it
|
|
120
120
|
// ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)), so a booted
|
|
121
121
|
// production artifact reports the lane it is running in too.
|
|
122
|
-
function isTestRun(
|
|
123
|
-
return !!
|
|
122
|
+
function isTestRun(omega) {
|
|
123
|
+
return !!omega?.isTesting?.();
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const authPersistence = {
|
|
127
127
|
_initialized: false,
|
|
128
|
-
|
|
128
|
+
_omega: null,
|
|
129
129
|
_strategies: {
|
|
130
130
|
safeStorage: safeStorageStrategy,
|
|
131
131
|
none: noneStrategy,
|
|
@@ -134,15 +134,15 @@ const authPersistence = {
|
|
|
134
134
|
|
|
135
135
|
// Lib-shape conformance — the real work happens in resolve(), called by the
|
|
136
136
|
// @omega.js/client bridge at auth boot (it needs the async availability check).
|
|
137
|
-
initialize(
|
|
137
|
+
initialize(omega) {
|
|
138
138
|
if (authPersistence._initialized) {
|
|
139
139
|
return;
|
|
140
140
|
}
|
|
141
|
-
authPersistence.
|
|
141
|
+
authPersistence._omega = omega;
|
|
142
142
|
authPersistence._initialized = true;
|
|
143
143
|
},
|
|
144
144
|
|
|
145
|
-
// Consumers add custom strategies before
|
|
145
|
+
// Consumers add custom strategies before omega.initialize().
|
|
146
146
|
register(name, strategy) {
|
|
147
147
|
if (!name || typeof strategy?.getItem !== 'function') {
|
|
148
148
|
throw new Error('auth-persistence.register: strategy must implement getItem/setItem/removeItem/available');
|
|
@@ -152,20 +152,20 @@ const authPersistence = {
|
|
|
152
152
|
|
|
153
153
|
// Pick + availability-check the configured strategy. Returns the active strategy
|
|
154
154
|
// or null (→ caller falls back to firebase's in-memory default).
|
|
155
|
-
async resolve(
|
|
155
|
+
async resolve(omega) {
|
|
156
156
|
// A TEST RUN is `none`, before any config is read: the test lanes never sign a
|
|
157
157
|
// real user in, so the OS keychain is never asked. This overrides an explicit
|
|
158
158
|
// consumer value too, because the boot layer boots the brand's REAL config through
|
|
159
159
|
// the staged test app, and an unsigned Electron binary asking macOS for a keychain
|
|
160
160
|
// item parks the whole run behind a SecurityAgent prompt
|
|
161
161
|
// ([#907](https://github.com/Omega-JS-Stack/omega/issues/907)).
|
|
162
|
-
if (isTestRun(
|
|
162
|
+
if (isTestRun(omega)) {
|
|
163
163
|
logger.log('auth persistence: none (test mode)');
|
|
164
164
|
authPersistence._active = null;
|
|
165
165
|
return null;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
const wanted =
|
|
168
|
+
const wanted = omega.config?.omega?.authPersistence || 'safeStorage';
|
|
169
169
|
const strategy = authPersistence._strategies[wanted];
|
|
170
170
|
|
|
171
171
|
if (!strategy) {
|