@omega.js/desktop 0.1.0 → 0.51.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 +1 -1
- package/dist/assets/css/tokens/_index.scss +1 -1
- package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +4 -1
- package/dist/assets/themes/base/_includes/frontend/sections/footer.html +13 -6
- package/dist/assets/themes/base/_includes/frontend/sections/nav.html +10 -8
- package/dist/assets/themes/base/_includes/global/sections/account.html +3 -1
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +12 -8
- package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +10 -6
- package/dist/assets/themes/base/_includes/global/sections/page-header.html +8 -4
- package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +24 -24
- package/dist/assets/themes/base/_layouts/frontend/pages/about.html +10 -10
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +35 -35
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +4 -4
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +4 -4
- package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/download.html +34 -33
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +11 -11
- package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/status.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +9 -7
- package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +5 -3
- package/dist/assets/themes/base/_sections/about/letter/section.html +1 -1
- package/dist/assets/themes/base/_sections/about/letter/section.json5 +4 -4
- package/dist/assets/themes/base/_sections/marketing/bento/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +15 -15
- package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +1 -1
- package/dist/assets/themes/base/_sections/marketing/hero/section.html +6 -6
- package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +10 -10
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +2 -2
- package/dist/assets/themes/base/_sections/marketing/stats/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +5 -5
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +2 -2
- package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +10 -10
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +10 -10
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +2 -2
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +4 -4
- package/dist/build.js +69 -28
- package/dist/cli-run.js +20 -13
- package/dist/cli.js +12 -7
- package/dist/commands/build.js +0 -2
- package/dist/commands/deploy.js +116 -44
- package/dist/commands/finalize-release.js +5 -4
- package/dist/commands/launch.js +12 -7
- package/dist/commands/lib/deploy-precheck.js +66 -34
- package/dist/commands/lib/ensure-target.js +71 -11
- package/dist/commands/package.js +0 -1
- package/dist/commands/publish.js +11 -4
- package/dist/commands/release.js +99 -252
- package/dist/commands/runner.js +42 -5
- package/dist/commands/sign-windows.js +46 -15
- package/dist/commands/test.js +4 -3
- package/dist/commands/validate-certs.js +291 -115
- package/dist/config/page-template.html +4 -0
- package/dist/defaults/.github/workflows/build.yml +144 -64
- package/dist/defaults/AGENTS.md +3 -2
- package/dist/defaults/_.gitignore +4 -2
- package/dist/defaults/config/certs/README.md +25 -45
- package/dist/defaults/config/omega.json5 +66 -32
- package/dist/defaults/hooks/deploy/pre.js +10 -0
- package/dist/defaults/src/assets/scss/main.scss +12 -2
- package/dist/defaults/src/integrations/tray/index.js +1 -1
- package/dist/gulp/main.js +13 -25
- package/dist/gulp/tasks/audit.js +18 -6
- package/dist/gulp/tasks/build-config.js +181 -60
- package/dist/gulp/tasks/bundle.js +108 -36
- package/dist/gulp/tasks/release.js +86 -4
- package/dist/gulp/tasks/sass.js +11 -0
- package/dist/hooks/lib/notarize-tools.js +137 -0
- package/dist/hooks/notarize-artifacts.js +57 -0
- package/dist/hooks/notarize.js +59 -8
- package/dist/lib/auth-persistence.js +25 -0
- package/dist/lib/client-bridge.js +11 -8
- package/dist/lib/deep-link.js +15 -8
- package/dist/lib/protocol.js +7 -1
- package/dist/lib/restart-manager/install.js +6 -3
- package/dist/lib/sign-helpers/auto-unlock.js +65 -27
- package/dist/lib/sign-helpers/console-lock.js +34 -0
- package/dist/lib/sign-helpers/exec-with-limit.js +68 -0
- package/dist/lib/sign-helpers/resolve-icons.js +6 -4
- package/dist/lib/tray.js +7 -6
- package/dist/main.js +16 -0
- package/dist/preload.js +8 -0
- package/dist/renderer.js +16 -4
- package/dist/runner/job-started.js +104 -0
- package/dist/test/fixtures/consumer-app/config/omega.json5 +7 -0
- package/dist/test/fixtures/consumer-app/package.json +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +7 -1
- package/dist/test/harness/main-entry.js +2 -1
- package/dist/test/harness/renderer-preload.js +12 -3
- package/dist/test/runners/boot.js +101 -11
- package/dist/test/runners/electron.js +1 -1
- package/dist/test/suites/boot/consumer-app-boots.test.js +54 -0
- package/dist/test/suites/build/audit.test.js +45 -6
- package/dist/test/suites/build/auth-persistence-resolve.test.js +119 -0
- package/dist/test/suites/build/auto-unlock.test.js +105 -0
- package/dist/test/suites/build/boot-runner-timeout.test.js +253 -0
- package/dist/test/suites/build/brand-scss.test.js +106 -0
- package/dist/test/suites/build/build-config.test.js +146 -36
- package/dist/test/suites/build/build-json-bake.test.js +245 -0
- package/dist/test/suites/build/build-verbs.test.js +48 -15
- package/dist/test/suites/build/build-workflow-jobs.test.js +190 -0
- package/dist/test/suites/build/cli.test.js +32 -10
- package/dist/test/suites/build/config-schema.test.js +4 -4
- package/dist/test/suites/build/console-lock.test.js +51 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +71 -2
- package/dist/test/suites/build/deploy-direct.test.js +241 -0
- package/dist/test/suites/build/deploy-dispatch.test.js +287 -0
- package/dist/test/suites/build/deploy-hook.test.js +169 -0
- package/dist/test/suites/build/ensure-target.test.js +14 -2
- package/dist/test/suites/build/env-delivery.test.js +19 -10
- package/dist/test/suites/build/env-watch.test.js +18 -7
- package/dist/test/suites/build/esm-only-dependency.test.js +127 -0
- package/dist/test/suites/build/exec-with-limit.test.js +53 -0
- package/dist/test/suites/build/finalize-release.test.js +2 -2
- package/dist/test/suites/build/get-config.test.js +120 -8
- package/dist/test/suites/build/github-utils.test.js +12 -6
- package/dist/test/suites/build/license-stamp.test.js +6 -4
- package/dist/test/suites/build/manager.test.js +88 -68
- package/dist/test/suites/build/manifest-deps.test.js +116 -0
- package/dist/test/suites/build/merge-line-files.test.js +27 -4
- package/dist/test/suites/build/notarize-artifacts.test.js +135 -0
- package/dist/test/suites/build/notarize-tools.test.js +38 -0
- package/dist/test/suites/build/notarize.test.js +207 -0
- package/dist/test/suites/build/release-pipeline.test.js +38 -60
- package/dist/test/suites/build/release-skipped-upload.test.js +107 -0
- package/dist/test/suites/build/resolve-icons.test.js +35 -35
- package/dist/test/suites/build/runner-job-guard.test.js +182 -0
- package/dist/test/suites/build/runner.test.js +25 -2
- package/dist/test/suites/build/sentry.test.js +8 -3
- package/dist/test/suites/build/setup-scripts.test.js +3 -0
- package/dist/test/suites/build/sign-windows.test.js +92 -8
- package/dist/test/suites/build/test-stealth.test.js +17 -11
- package/dist/test/suites/build/url-helpers.test.js +37 -17
- package/dist/test/suites/build/validate-certs.test.js +428 -55
- package/dist/test/suites/build/validate-config.test.js +3 -3
- package/dist/test/suites/main/auth-flow.test.js +12 -0
- package/dist/test/suites/main/auth-persistence.test.js +14 -17
- package/dist/test/suites/main/auto-updater.test.js +2 -2
- package/dist/test/suites/main/boot-sequence.test.js +1 -1
- package/dist/test/suites/main/client-bridge.integration.test.js +5 -82
- package/dist/test/suites/main/client-bridge.test.js +19 -6
- package/dist/test/suites/main/deep-link.test.js +54 -0
- package/dist/test/suites/main/startup-paths-and-ua.test.js +1 -1
- package/dist/test/suites/main/url-helpers.test.js +81 -72
- package/dist/test/suites/renderer/cross-context-helpers.test.js +19 -16
- package/dist/utils/build-pipeline.js +10 -10
- package/dist/utils/github.js +12 -51
- package/dist/utils/load-env.js +66 -0
- package/dist/utils/mode-helpers.js +43 -111
- package/dist/utils/platform.js +37 -0
- package/dist/utils/runner-env.js +2 -1
- package/dist/utils/runner-job-guard.js +149 -0
- package/dist/utils/ship-keys.js +52 -0
- package/dist/utils/test-stealth.js +5 -3
- package/dist/utils/url-helpers.js +33 -17
- package/dist/vendor/config/bundle-id.js +53 -0
- package/dist/vendor/config/client-config.js +141 -0
- package/dist/vendor/config/company.js +334 -15
- package/dist/vendor/config/dev-facts.js +48 -0
- package/dist/vendor/config/env-delivery.js +231 -9
- package/dist/vendor/config/env-retired.js +137 -0
- package/dist/vendor/config/env-rules.js +22 -3
- package/dist/vendor/config/env-schema.js +234 -117
- package/dist/vendor/config/env.js +55 -26
- package/dist/vendor/config/environment.js +189 -0
- package/dist/vendor/config/hooks.js +13 -11
- package/dist/vendor/config/index.js +121 -44
- package/dist/vendor/config/load.js +366 -115
- package/dist/vendor/config/merge.js +2 -2
- package/dist/vendor/config/order.js +3 -3
- package/dist/vendor/config/platforms.js +276 -0
- package/dist/vendor/config/repo.js +226 -104
- package/dist/vendor/config/retired-keys.js +232 -27
- package/dist/vendor/config/schema.js +525 -99
- package/dist/vendor/config/site-global.js +63 -53
- package/dist/vendor/config/targets.js +187 -0
- package/dist/vendor/config/validate.js +119 -59
- package/dist/vendor/devkit/argv.js +118 -0
- package/dist/vendor/devkit/attach-log-file.js +21 -13
- package/dist/vendor/devkit/brand-tokens.js +278 -0
- package/dist/vendor/devkit/brand-version.js +264 -0
- package/dist/vendor/devkit/build-json.js +91 -0
- package/dist/vendor/devkit/bundle.js +48 -0
- package/dist/vendor/devkit/certificate-expiry.js +108 -0
- package/dist/vendor/devkit/certs.js +16 -194
- package/dist/vendor/devkit/ci-workflows.js +124 -8
- package/dist/vendor/devkit/cli-router.js +3 -3
- package/dist/vendor/devkit/defaults-engine.js +69 -7
- package/dist/vendor/devkit/deploy-follow.js +297 -0
- package/dist/vendor/devkit/deploy-precheck.js +23 -8
- package/dist/vendor/devkit/deploy-record.js +11 -27
- package/dist/vendor/devkit/deploy-snapshot.js +661 -0
- package/dist/vendor/devkit/deploy.js +445 -75
- package/dist/vendor/devkit/git-auth.js +73 -0
- package/dist/vendor/devkit/git-remote.js +95 -0
- package/dist/vendor/devkit/github-repo.js +290 -0
- package/dist/vendor/devkit/local.js +47 -0
- package/dist/vendor/devkit/merge-line-files.js +23 -16
- package/dist/vendor/devkit/omega-bin.js +18 -3
- package/dist/vendor/devkit/pack-local.js +391 -0
- package/dist/vendor/devkit/preludes/index.js +120 -0
- package/dist/vendor/devkit/preludes/origin-heal.js +156 -0
- package/dist/vendor/devkit/service-account.js +43 -0
- package/dist/vendor/devkit/ship-plan.js +112 -0
- package/dist/vendor/devkit/signing-env.js +180 -0
- package/dist/vendor/devkit/signing-tree.js +92 -0
- package/dist/vendor/devkit/target-seams.js +142 -0
- package/dist/vendor/devkit/target-secrets.js +235 -50
- package/dist/vendor/devkit/test/esm-only-fixture.js +48 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/browser.js +19 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/index.js +20 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/package.json +13 -0
- package/dist/vendor/monitoring/env.js +20 -10
- 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 +1 -1
- package/docs/auto-updater.md +5 -5
- package/docs/boot-sequence.md +1 -1
- package/docs/build-system.md +15 -7
- package/docs/client-bridge.md +9 -7
- package/docs/config-schema.md +4 -4
- package/docs/css.md +8 -2
- package/docs/deep-link.md +12 -4
- package/docs/environment-detection.md +32 -24
- package/docs/hooks.md +3 -1
- package/docs/icons.md +7 -7
- package/docs/index.md +61 -23
- package/docs/installer-options.md +24 -21
- package/docs/logging.md +5 -5
- package/docs/releasing.md +25 -17
- package/docs/runner.md +40 -5
- package/docs/shared/brands.md +12 -6
- package/docs/shared/breaking-changes.md +375 -21
- package/docs/shared/config.md +757 -199
- package/docs/shared/deploys.md +194 -91
- package/docs/shared/icons.md +18 -0
- package/docs/shared/local-dev.md +24 -6
- package/docs/shared/logging.md +9 -6
- package/docs/shared/monitoring.md +27 -13
- package/docs/shared/publishing.md +19 -15
- package/docs/shared/rulings.md +2 -2
- package/docs/shared/testing.md +1 -1
- package/docs/shared/theming.md +26 -1
- package/docs/shared/translation.md +49 -7
- package/docs/shared/updates.md +3 -3
- package/docs/signing.md +59 -33
- package/docs/test-framework.md +10 -5
- package/docs/themes.md +15 -1
- package/package.json +18 -12
- package/bin/omega-desktop +0 -2
- package/dist/commands/push-secrets.js +0 -141
- package/dist/test/suites/build/deliver-certs.test.js +0 -95
- package/dist/test/suites/build/derive-signing-env.test.js +0 -122
- package/dist/test/suites/build/push-secrets.test.js +0 -226
- package/dist/test/suites/build/resolve-signing-cert.test.js +0 -342
- package/dist/utils/deliver-certs.js +0 -69
- package/dist/utils/derive-signing-env.js +0 -56
- package/dist/utils/resolve-signing-cert.js +0 -175
- package/dist/vendor/config/desktop-artifacts.js +0 -110
- package/dist/vendor/config/instances.js +0 -208
- /package/dist/defaults/config/icons/{macos → mac}/dmg.png +0 -0
- /package/dist/defaults/config/icons/{macos → mac}/icon.png +0 -0
- /package/dist/defaults/config/icons/{macos → mac}/tray.png +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The ship-credential check every publish runs FIRST
|
|
2
|
+
// ([#867](https://github.com/Omega-JS-Stack/omega/issues/867)).
|
|
3
|
+
//
|
|
4
|
+
// A format this brand DECLARES is one it means to ship, so a credential that
|
|
5
|
+
// format cannot publish without is a release that dies on a runner: the snap
|
|
6
|
+
// leg with no Snap Store login, the Windows leg with no credential for the
|
|
7
|
+
// signing strategy it configured. Both used to surface minutes into a build,
|
|
8
|
+
// or (worse) as a silently skipped target.
|
|
9
|
+
//
|
|
10
|
+
// What is owed comes from @omega.js/config's format table, narrowed to this
|
|
11
|
+
// brand by the env schema's own `requiredWhen` gates, so a brand that never
|
|
12
|
+
// mentions the snap owes nothing and a brand that writes
|
|
13
|
+
// `platforms.linux.formats.snap` owes the login. The refusal carries the same
|
|
14
|
+
// line shape push-secrets prints
|
|
15
|
+
// ([#891](https://github.com/Omega-JS-Stack/omega/issues/891)) and names the
|
|
16
|
+
// ONE walk that collects it, exactly as the extension publish does.
|
|
17
|
+
//
|
|
18
|
+
// A BUILD is not a publish: it keeps its clean skip (gulp/build-config drops
|
|
19
|
+
// the snap target when the login is absent), because nothing is being put in
|
|
20
|
+
// front of users.
|
|
21
|
+
|
|
22
|
+
const { shipPlan, missingShipKeys, shipKeyRefusal } = require('../vendor/devkit/ship-plan.js');
|
|
23
|
+
|
|
24
|
+
const Manager = new (require('../build.js'));
|
|
25
|
+
const logger = Manager.logger('ship-keys');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Refuse a publish whose declared formats have no credential to ship with.
|
|
29
|
+
*
|
|
30
|
+
* @param {object} [options]
|
|
31
|
+
* @param {object} [options.config] - Resolved config (default: the consumer's).
|
|
32
|
+
* @param {object} [options.env] - Env map (default: process.env).
|
|
33
|
+
* @returns {Array<object>} The ship plan (what this brand ships).
|
|
34
|
+
* @throws {Error} Naming every missing key, its declaration, and the walk.
|
|
35
|
+
*/
|
|
36
|
+
function assertShipKeys(options) {
|
|
37
|
+
options = options || {};
|
|
38
|
+
|
|
39
|
+
const config = options.config || Manager.getConfig();
|
|
40
|
+
const plan = shipPlan(config, 'desktop');
|
|
41
|
+
const missing = missingShipKeys(plan, options.env || process.env);
|
|
42
|
+
|
|
43
|
+
if (missing.length > 0) {
|
|
44
|
+
throw new Error(shipKeyRefusal(missing));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
logger.log(`Shipping ${plan.map((entry) => `${entry.platform}/${entry.format}`).join(', ')}`);
|
|
48
|
+
|
|
49
|
+
return plan;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = { assertShipKeys };
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
// which initializes its Manager only after app ready (too late to prevent
|
|
12
12
|
// the launch activation)
|
|
13
13
|
//
|
|
14
|
-
// Pass the Manager when you have one
|
|
15
|
-
// config
|
|
16
|
-
//
|
|
14
|
+
// Pass the Manager when you have one: its isTesting() reads the environment the
|
|
15
|
+
// Manager's own config was baked with. Without one (the harness, pre-Manager
|
|
16
|
+
// code) the standalone check reads the process's OMEGA_ENVIRONMENT, the one
|
|
17
|
+
// input every lane sets ([#817](https://github.com/Omega-JS-Stack/omega/issues/817));
|
|
18
|
+
// the test runners spawn their children naming `testing`.
|
|
17
19
|
//
|
|
18
20
|
// Usage:
|
|
19
21
|
// const isTestStealth = require('./utils/test-stealth.js');
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
// callers normally pass NO argument. An explicit `environment` arg is an override
|
|
12
12
|
// (used mainly by tests to pin a specific environment's mapping).
|
|
13
13
|
|
|
14
|
+
// The missing-fact error is the ONE shared one (#834). Its module requires
|
|
15
|
+
// nothing, so it rides the renderer bundle exactly as this file does.
|
|
16
|
+
const { devFactMissing } = require('../vendor/config/dev-facts.js');
|
|
17
|
+
|
|
14
18
|
// Guarded the way @omega.js/extension's twin is: the renderer bundle is a
|
|
15
19
|
// browser context, and only the Node-side contexts (main, preload, build, the
|
|
16
20
|
// test harness) carry the resolved-port env channel.
|
|
@@ -20,14 +24,9 @@ function envPort(name) {
|
|
|
20
24
|
: undefined;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
// The
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
// Node-only package (fs, net, json5); @omega.js/client mirrors the same constant
|
|
27
|
-
// for the same reason. The build suite pins this copy to the config package's
|
|
28
|
-
// value, so a drift fails a test instead of a user
|
|
29
|
-
// ([#747](https://github.com/Omega-JS-Stack/omega/issues/747)).
|
|
30
|
-
const CLASSIC_DEV_ORIGIN = 'https://localhost:4000';
|
|
27
|
+
// The step that writes the resolved dev map into this surface's artifact, named
|
|
28
|
+
// in every missing-fact error below (#834).
|
|
29
|
+
const DEV_FACT_WRITER = "@omega.js/desktop's bundle task, from the live stack's ports file plus the OMEGA_*_PORT env channel";
|
|
31
30
|
|
|
32
31
|
// One local port, from whichever channel this context has: the env var first
|
|
33
32
|
// (the CLI that booted the stack publishes it, N7), then the `dev.ports` map
|
|
@@ -35,10 +34,26 @@ const CLASSIC_DEV_ORIGIN = 'https://localhost:4000';
|
|
|
35
34
|
// parent env, so a bumped emulator port reaches it only that way
|
|
36
35
|
// ([#745](https://github.com/Omega-JS-Stack/omega/issues/745)). Same helper,
|
|
37
36
|
// same order as @omega.js/extension's src/utils/url-helpers.js.
|
|
37
|
+
//
|
|
38
|
+
// There is no third step any more (#834): the classic numbers used to be
|
|
39
|
+
// hand-typed here as a last resort for "a build made with no stack up", which
|
|
40
|
+
// is a guess about a port nothing identity-checks. A miss is loud instead.
|
|
38
41
|
function localPort(context, envName, name) {
|
|
39
42
|
return envPort(envName) || context?.config?.dev?.ports?.[name];
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
// The same read, REQUIRED: the one every URL getter below uses, because every
|
|
46
|
+
// one of them is answering with a real local address or not at all.
|
|
47
|
+
function requiredPort(context, envName, name) {
|
|
48
|
+
const port = localPort(context, envName, name);
|
|
49
|
+
|
|
50
|
+
if (!port) {
|
|
51
|
+
throw devFactMissing(`dev port for \`${name}\``, DEV_FACT_WRITER);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return port;
|
|
55
|
+
}
|
|
56
|
+
|
|
42
57
|
function getFunctionsUrl(environment) {
|
|
43
58
|
const env = environment || this.getEnvironment();
|
|
44
59
|
const projectId = this?.config?.cloud?.config?.projectId;
|
|
@@ -51,7 +66,7 @@ function getFunctionsUrl(environment) {
|
|
|
51
66
|
// same three-step chain getApiUrl() walks: the OMEGA_*_PORT env channel (N7),
|
|
52
67
|
// then the baked map, then the classic default.
|
|
53
68
|
if (env === 'development' || env === 'testing') {
|
|
54
|
-
const port =
|
|
69
|
+
const port = requiredPort(this, 'OMEGA_FUNCTIONS_PORT', 'functions');
|
|
55
70
|
return `http://localhost:${port}/${projectId}/us-central1`;
|
|
56
71
|
}
|
|
57
72
|
|
|
@@ -64,12 +79,13 @@ function getApiUrl(environment) {
|
|
|
64
79
|
// Local for development OR testing; production otherwise. Mirrors
|
|
65
80
|
// @omega.js/backend's getApiUrl (N7): a resolved OMEGA_HTTPS_PORT means
|
|
66
81
|
// `mgr serve`'s mkcert proxy is up (https); otherwise plain http to the
|
|
67
|
-
// hosting emulator (env port, baked port
|
|
82
|
+
// hosting emulator (env port, then baked port). Neither resolved is a broken
|
|
83
|
+
// build, not a case to assume the classic 5002 through (#834).
|
|
68
84
|
if (env === 'development' || env === 'testing') {
|
|
69
85
|
const httpsPort = localPort(this, 'OMEGA_HTTPS_PORT', 'https');
|
|
70
86
|
return httpsPort
|
|
71
87
|
? `https://localhost:${httpsPort}`
|
|
72
|
-
: `http://localhost:${
|
|
88
|
+
: `http://localhost:${requiredPort(this, 'OMEGA_HOSTING_PORT', 'hosting')}`;
|
|
73
89
|
}
|
|
74
90
|
|
|
75
91
|
// Prod: api.<brand host>. Mirrors @omega.js/client.getApiUrl. Never derive
|
|
@@ -89,9 +105,10 @@ function getApiUrl(environment) {
|
|
|
89
105
|
// ([#262](https://github.com/Omega-JS-Stack/omega/issues/262)): the baked
|
|
90
106
|
// `dev.origin` the live website published (scheme, host AND port, the complete
|
|
91
107
|
// fact) wins, else a port from the usual chain (OMEGA_WEBSITE_PORT, then the baked
|
|
92
|
-
// `dev.ports.website`) composed over https
|
|
93
|
-
//
|
|
94
|
-
//
|
|
108
|
+
// `dev.ports.website`) composed over https. There is no classic-origin fallback
|
|
109
|
+
// any more (#834): a wrong dev origin fails as a silent connection refusal. The
|
|
110
|
+
// scheme is https because `omega dev` fronts its public port with the mkcert
|
|
111
|
+
// proxy by default, so a port alone can never say it
|
|
95
112
|
// ([#747](https://github.com/Omega-JS-Stack/omega/issues/747)).
|
|
96
113
|
// Prod → `config.brand.url`. Use this whenever app code wants to link out to "the
|
|
97
114
|
// website" (Help → Website tray/menu items, "Open in browser," billing portal
|
|
@@ -106,8 +123,7 @@ function getWebsiteUrl(environment) {
|
|
|
106
123
|
return origin;
|
|
107
124
|
}
|
|
108
125
|
|
|
109
|
-
|
|
110
|
-
return port ? `https://localhost:${port}` : CLASSIC_DEV_ORIGIN;
|
|
126
|
+
return `https://localhost:${requiredPort(this, 'OMEGA_WEBSITE_PORT', 'website')}`;
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
const url = this?.config?.brand?.url;
|
|
@@ -160,8 +176,8 @@ function attachTo(Manager) {
|
|
|
160
176
|
|
|
161
177
|
module.exports = {
|
|
162
178
|
attachTo,
|
|
163
|
-
CLASSIC_DEV_ORIGIN,
|
|
164
179
|
localPort,
|
|
180
|
+
requiredPort,
|
|
165
181
|
getFunctionsUrl,
|
|
166
182
|
getApiUrl,
|
|
167
183
|
getWebsiteUrl,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundle-identifier policy — reverse-DNS ids derived from the brand's web
|
|
3
|
+
* identity (Ian 2026-07-14: the prefix is the reverse domain, autoset at
|
|
4
|
+
* onboarding from the parent company when one exists, else the brand's own
|
|
5
|
+
* url).
|
|
6
|
+
*
|
|
7
|
+
* deriveBundleIdPrefix('https://itwcreativeworks.com') → 'com.itwcreativeworks'
|
|
8
|
+
* deriveBundleIdPrefix('https://playground.omegajs.dev') → 'dev.omegajs.playground'
|
|
9
|
+
* composeBundleId('com.itwcreativeworks', 'daily-build')
|
|
10
|
+
* → 'com.itwcreativeworks.daily.build'
|
|
11
|
+
*
|
|
12
|
+
* Sanitization keeps ids legal on BOTH stores: Apple allows hyphens but
|
|
13
|
+
* Android package segments don't, so domain labels drop non-alphanumerics
|
|
14
|
+
* and brand-id hyphens become dots (each id word is its own segment).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reverse-DNS prefix from a company/brand url, or null when the url does
|
|
19
|
+
* not parse. `www.` is dropped; every other hostname label survives (a
|
|
20
|
+
* subdomain brand derives a subdomain-scoped prefix).
|
|
21
|
+
*
|
|
22
|
+
* @param {string} url - http(s) url (brand.url shape)
|
|
23
|
+
* @returns {string|null}
|
|
24
|
+
*/
|
|
25
|
+
function deriveBundleIdPrefix(url) {
|
|
26
|
+
let hostname;
|
|
27
|
+
try {
|
|
28
|
+
hostname = new URL(url).hostname;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const labels = hostname
|
|
34
|
+
.replace(/^www\./, '')
|
|
35
|
+
.split('.')
|
|
36
|
+
.map((label) => label.toLowerCase().replace(/[^a-z0-9]/g, ''))
|
|
37
|
+
.filter(Boolean);
|
|
38
|
+
|
|
39
|
+
return labels.length > 0 ? labels.reverse().join('.') : null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Full bundle identifier: prefix + the brand id with hyphens as dots.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} prefix - reverse-DNS prefix (config or derived)
|
|
46
|
+
* @param {string} brandId - brand.id ('daily-build')
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
function composeBundleId(prefix, brandId) {
|
|
50
|
+
return `${prefix}.${String(brandId).toLowerCase().replace(/-+/g, '.')}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { deriveBundleIdPrefix, composeBundleId };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client-config.js: the ONE browser-safe subset of a resolved config
|
|
3
|
+
* ([#894](https://github.com/Omega-JS-Stack/omega/issues/894)).
|
|
4
|
+
*
|
|
5
|
+
* Three surfaces bake a config into an artifact a browser can read: web's page
|
|
6
|
+
* chrome, desktop's renderer bundle, and every extension bundle. Each one used
|
|
7
|
+
* to decide what may go public on its own, three different ways (desktop
|
|
8
|
+
* shipped the WHOLE resolved config, the extension kept a hand-written allow
|
|
9
|
+
* list, web wired a subset together in its engine and its foot include), so a
|
|
10
|
+
* new public value had to be added in three places and every one of them could
|
|
11
|
+
* be the place it leaked.
|
|
12
|
+
*
|
|
13
|
+
* This is that decision, once. The schema's `CLIENT_SECTIONS` says which
|
|
14
|
+
* sections a browser may see (and how much of each), the list below says which
|
|
15
|
+
* BUILD FACTS ride beside them, and nothing else leaves the build. All three
|
|
16
|
+
* bakes call this and wrap the answer identically:
|
|
17
|
+
*
|
|
18
|
+
* OMEGA_BUILD_JSON = { config: clientConfig(resolved), package, mode, license, builtAt }
|
|
19
|
+
*
|
|
20
|
+
* Secrets are a loud failure, not a filter: a secret-shaped key inside a
|
|
21
|
+
* section that is about to ship means the resolved config carried one at all,
|
|
22
|
+
* which loadConfig() and validateConfig() already refuse. A value a build is
|
|
23
|
+
* SANCTIONED to bake (`publicAtRest`, docs/shared/config.md) comes from .env
|
|
24
|
+
* and is added by that build after this gate, never carried through it.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const { CLIENT_SECTIONS } = require('./schema.js');
|
|
28
|
+
const { findSecretKeys } = require('./secrets.js');
|
|
29
|
+
const { resolveWinbackOffer } = require('./winback.js');
|
|
30
|
+
|
|
31
|
+
// The per-build facts a surface composes ON TOP of the resolved config before
|
|
32
|
+
// baking it. They are not config sections (nothing authors them in
|
|
33
|
+
// omega.json5): each is a fact about the artifact, spelled the same on every
|
|
34
|
+
// surface so one read answers everywhere.
|
|
35
|
+
//
|
|
36
|
+
// runtime 'web' | 'browser-extension' | 'electron'
|
|
37
|
+
// environment the build's verdict ('development' | 'testing' | 'production')
|
|
38
|
+
// version the target's own package version, the release tag every error
|
|
39
|
+
// report carries as `<brand.id>@<version>` (#380)
|
|
40
|
+
// buildTime the build stamp (ms)
|
|
41
|
+
// target WHICH target this artifact IS, by name (#887)
|
|
42
|
+
// url this target's own resolved public url (#588)
|
|
43
|
+
// dev the local stack's resolved map: ports + the sibling website's
|
|
44
|
+
// origin, development builds only (#300/#262). The extension's
|
|
45
|
+
// live-reload port rides here too (#896), the one home of a
|
|
46
|
+
// local-stack number.
|
|
47
|
+
const CLIENT_FACT_KEYS = ['runtime', 'environment', 'version', 'buildTime', 'target', 'url', 'dev'];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Copy exactly `paths` out of a section (dot-paths, deep).
|
|
51
|
+
* @param {*} section - the resolved section value.
|
|
52
|
+
* @param {string[]} paths - dot-paths inside it.
|
|
53
|
+
* @returns {object|undefined} the picked sub-tree, or undefined when it is empty.
|
|
54
|
+
*/
|
|
55
|
+
function pickPaths(section, paths) {
|
|
56
|
+
if (!section || typeof section !== 'object') {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const picked = {};
|
|
61
|
+
let found = false;
|
|
62
|
+
|
|
63
|
+
for (const path of paths) {
|
|
64
|
+
const keys = path.split('.');
|
|
65
|
+
let source = section;
|
|
66
|
+
let missing = false;
|
|
67
|
+
|
|
68
|
+
for (const key of keys) {
|
|
69
|
+
if (!source || typeof source !== 'object' || !(key in source)) {
|
|
70
|
+
missing = true;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
source = source[key];
|
|
74
|
+
}
|
|
75
|
+
if (missing) continue;
|
|
76
|
+
|
|
77
|
+
let cursor = picked;
|
|
78
|
+
for (const key of keys.slice(0, -1)) {
|
|
79
|
+
cursor[key] = cursor[key] || {};
|
|
80
|
+
cursor = cursor[key];
|
|
81
|
+
}
|
|
82
|
+
cursor[keys[keys.length - 1]] = source;
|
|
83
|
+
found = true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return found ? picked : undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The subset of a resolved config a browser may see.
|
|
91
|
+
* @param {object} [resolved] - a resolved config (Manager.getConfig() output),
|
|
92
|
+
* with this build's facts composed onto it.
|
|
93
|
+
* @returns {object} the blob every browser surface bakes as OMEGA_BUILD_JSON.config.
|
|
94
|
+
* @throws {Error} when a section that is about to ship carries a secret-shaped key.
|
|
95
|
+
*/
|
|
96
|
+
function clientConfig(resolved) {
|
|
97
|
+
const source = resolved || {};
|
|
98
|
+
const client = {};
|
|
99
|
+
|
|
100
|
+
for (const key of CLIENT_FACT_KEYS) {
|
|
101
|
+
if (key in source) client[key] = source[key];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (const [section, rule] of Object.entries(CLIENT_SECTIONS)) {
|
|
105
|
+
if (!(section in source)) continue;
|
|
106
|
+
|
|
107
|
+
const value = rule === true ? source[section] : pickPaths(source[section], rule);
|
|
108
|
+
if (value === undefined) continue;
|
|
109
|
+
|
|
110
|
+
client[section] = value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// A secret in here is not a value to drop: it is a config that should never
|
|
114
|
+
// have loaded, so it fails the build at the one place that would have
|
|
115
|
+
// published it.
|
|
116
|
+
const secrets = findSecretKeys(client);
|
|
117
|
+
if (secrets.length) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
`[@omega.js/config] refusing to bake a browser config carrying secret-shaped keys: ${secrets.join(', ')}. `
|
|
120
|
+
+ 'Secrets live in .env, never in config/omega.json5 (docs/shared/config.md).',
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// The one home of the cancel-flow save offer's default (#268) is
|
|
125
|
+
// @omega.js/config, so the browser is handed the RESOLVED offer: the dialog a
|
|
126
|
+
// customer reads and the coupon the backend creates can never name different
|
|
127
|
+
// numbers.
|
|
128
|
+
if (client.payment) {
|
|
129
|
+
client.payment = { ...client.payment, winback: resolveWinbackOffer(client.payment) };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Never an alias of the resolved config: what a bake stamps into an artifact
|
|
133
|
+
// cannot be something a later build step can still mutate. A JSON round trip
|
|
134
|
+
// and not structuredClone, because JSON is what a bake CAN carry: a page's
|
|
135
|
+
// resolved config arrives through a template data cascade that hangs
|
|
136
|
+
// functions and accessors off it, and those drop out here rather than
|
|
137
|
+
// crashing the build.
|
|
138
|
+
return JSON.parse(JSON.stringify(client));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = { clientConfig, CLIENT_FACT_KEYS };
|