@omega.js/desktop 0.50.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 +3 -3
- 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 +1 -1
- 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
|
@@ -1,142 +1,264 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @omega.js/config repo
|
|
3
|
-
* (
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
2
|
+
* @omega.js/config repo: the ONE derivation of every repo a brand owns
|
|
3
|
+
* ([#883](https://github.com/Omega-JS-Stack/omega/issues/883)).
|
|
4
|
+
*
|
|
5
|
+
* ONE config block says where a brand hosts its code:
|
|
6
|
+
*
|
|
7
|
+
* repo: { provider: 'github', org: 'Acme-Org' }
|
|
8
|
+
*
|
|
9
|
+
* and nothing else. Presence of the block enables the repo service, exactly
|
|
10
|
+
* as a target's key presence enables a target; `provider` defaults to `github`
|
|
11
|
+
* and `org` is the only typed value. No repo NAME is ever configured: every
|
|
12
|
+
* name derives from the `<brand.id>-<role>` rule (Ian 2026-09-07,
|
|
13
|
+
* [#809](https://github.com/Omega-JS-Stack/omega/issues/809)), one function per
|
|
14
|
+
* role, so nobody types a repo name to get the right one:
|
|
15
|
+
*
|
|
16
|
+
* - `<brand.id>-omega` the SOURCE monorepo (`sourceRepo`)
|
|
17
|
+
* - `<brand.id>-releases` the public release channel (`releasesRepo`)
|
|
18
|
+
* - `<brand.id>-<name>` one per web target that GitHub hosts (`websiteRepo`)
|
|
19
|
+
*
|
|
20
|
+
* A repo name that must differ is a brand id that must differ: the override
|
|
21
|
+
* keys (`repo.providers.github.repo`, the top-level `github` block,
|
|
22
|
+
* `targets.<name>.github.repo`, `targets.desktop.releases.owner/repo`) are
|
|
23
|
+
* retired, each with a row in retired-keys.js.
|
|
24
|
+
*
|
|
25
|
+
* Visibility is NOT in omega.json5 either: the brand root's package.json
|
|
26
|
+
* `private` field is the one statement of it (`brandVisibility`), absent
|
|
27
|
+
* meaning private, because every brand monorepo is private by default
|
|
28
|
+
* (Ian 2026-09-11).
|
|
26
29
|
*/
|
|
27
30
|
|
|
31
|
+
const fs = require('node:fs');
|
|
32
|
+
const path = require('node:path');
|
|
33
|
+
|
|
34
|
+
const { isPlainObject } = require('./merge.js');
|
|
35
|
+
const { targetUrl, brandHost } = require('./targets.js');
|
|
36
|
+
// The two provider lists live in schema.js, with the rules that enumerate
|
|
37
|
+
// them (the WINBACK_DURATIONS pattern), and are re-exported here: this module
|
|
38
|
+
// is where every reader takes them from.
|
|
39
|
+
const { REPO_PROVIDERS, HOSTING_PROVIDERS } = require('./schema.js');
|
|
40
|
+
|
|
41
|
+
const DEFAULT_REPO_PROVIDER = 'github';
|
|
42
|
+
|
|
43
|
+
// Every GitHub default Pages host (`<owner>.github.io`, and the bare form): a
|
|
44
|
+
// url naming one is an ADDRESS, never a custom domain (#366).
|
|
45
|
+
const DEFAULT_PAGES_HOST = /(^|\.)github\.io$/i;
|
|
46
|
+
const DEFAULT_HOSTING_PROVIDER = 'github';
|
|
47
|
+
|
|
28
48
|
/**
|
|
29
|
-
*
|
|
49
|
+
* The brand's repo block: `{ provider, org }`, with the provider defaulted.
|
|
30
50
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
51
|
+
* Null when the config carries no `repo` block, and null when the block names
|
|
52
|
+
* no org: half an address addresses nothing, and the validator fails an
|
|
53
|
+
* org-less block on its own (an error here would be a second, quieter copy of
|
|
54
|
+
* that rule).
|
|
55
|
+
*
|
|
56
|
+
* @param {object} config - Composed omega config (brand + local layers).
|
|
57
|
+
* @returns {{ provider: string, org: string }|null}
|
|
33
58
|
*/
|
|
34
|
-
function
|
|
35
|
-
const
|
|
36
|
-
if (!
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
function repoBlock(config) {
|
|
60
|
+
const repo = config ? config.repo : undefined;
|
|
61
|
+
if (!isPlainObject(repo)) return null;
|
|
62
|
+
|
|
63
|
+
const org = typeof repo.org === 'string' ? repo.org.trim() : '';
|
|
64
|
+
if (!org) return null;
|
|
65
|
+
|
|
66
|
+
return { provider: repo.provider || DEFAULT_REPO_PROVIDER, org };
|
|
40
67
|
}
|
|
41
68
|
|
|
42
69
|
/**
|
|
43
|
-
* The
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
70
|
+
* The brand's id, trimmed: the role suffix is appended to it, so untrimmed
|
|
71
|
+
* whitespace would sit INSIDE the derived name.
|
|
72
|
+
* @param {object} config - Composed omega config.
|
|
73
|
+
* @returns {string} '' when the config names no brand id.
|
|
74
|
+
*/
|
|
75
|
+
function brandId(config) {
|
|
76
|
+
const id = config && config.brand ? config.brand.id : undefined;
|
|
77
|
+
return typeof id === 'string' ? id.trim() : '';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A derived repo as one finished value, or null when either half is missing.
|
|
82
|
+
* @param {object} config - Composed omega config.
|
|
83
|
+
* @param {string} role - The role suffix ('omega', 'releases', a target name).
|
|
84
|
+
* @returns {{ owner: string, name: string, slug: string }|null}
|
|
50
85
|
*/
|
|
51
|
-
function
|
|
52
|
-
|
|
86
|
+
function derivedRepo(config, role) {
|
|
87
|
+
const block = repoBlock(config);
|
|
88
|
+
const id = brandId(config);
|
|
89
|
+
if (!block || !id) return null;
|
|
90
|
+
|
|
91
|
+
const name = `${id}-${role}`;
|
|
92
|
+
|
|
93
|
+
return { owner: block.org, name, slug: `${block.org}/${name}` };
|
|
53
94
|
}
|
|
54
95
|
|
|
55
96
|
/**
|
|
56
|
-
* The brand
|
|
57
|
-
*
|
|
97
|
+
* The brand's SOURCE monorepo: `<brand.id>-omega` under the declared org. This
|
|
98
|
+
* is the repo every SOURCE fact addresses: the workflow dispatch, the repo
|
|
99
|
+
* Actions secrets, the CMS content commits, the scaffolded workflows.
|
|
58
100
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
101
|
+
* Its visibility is the brand root's `private` field (`brandVisibility`), not a
|
|
102
|
+
* config key.
|
|
103
|
+
*
|
|
104
|
+
* @param {object} config - Composed omega config.
|
|
105
|
+
* @returns {{ owner: string, name: string, slug: string }|null} Null when the config names no org or no brand id.
|
|
61
106
|
*/
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
// The id half is trimmed like a typed slug: the role suffix is appended to
|
|
65
|
-
// it, so untrimmed whitespace would sit INSIDE the composed name.
|
|
66
|
-
const id = (config?.brand?.id || '').trim();
|
|
67
|
-
|
|
68
|
-
return parseRepoSlug(github.repo).name
|
|
69
|
-
|| (id ? `${id}-omega` : '');
|
|
107
|
+
function sourceRepo(config) {
|
|
108
|
+
return derivedRepo(config, 'omega');
|
|
70
109
|
}
|
|
71
110
|
|
|
72
111
|
/**
|
|
73
|
-
* The brand
|
|
112
|
+
* The brand's ONE public releases repo: `<brand.id>-releases` under the same
|
|
113
|
+
* org, ALWAYS public, because the desktop updater polls it with no token
|
|
114
|
+
* ([#620](https://github.com/Omega-JS-Stack/omega/issues/620),
|
|
115
|
+
* [#799](https://github.com/Omega-JS-Stack/omega/issues/799)).
|
|
74
116
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
117
|
+
* It is the release channel for EVERY target's built artifacts (desktop
|
|
118
|
+
* installers and the extension's zips alike, tagged per target) and the one
|
|
119
|
+
* home of that address: the site's download links, @omega.js/desktop's
|
|
120
|
+
* electron-builder publish block and its finalize-release upload all read it
|
|
121
|
+
* here, so the feed a shipped app polls can never disagree with the URL a
|
|
122
|
+
* download button carries.
|
|
123
|
+
*
|
|
124
|
+
* @param {object} config - Composed omega config.
|
|
125
|
+
* @returns {{ owner: string, name: string, slug: string }|null} Null when the config names no org or no brand id.
|
|
126
|
+
*/
|
|
127
|
+
function releasesRepo(config) {
|
|
128
|
+
return derivedRepo(config, 'releases');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A declared target's entry, by name.
|
|
133
|
+
* @param {object} config - Composed omega config carrying `targets`.
|
|
134
|
+
* @param {string} name - The target name.
|
|
135
|
+
* @returns {object} The entry.
|
|
136
|
+
* @throws {Error} When the config declares no target of that name.
|
|
137
|
+
*/
|
|
138
|
+
function targetEntry(config, name) {
|
|
139
|
+
const targets = config && config.targets;
|
|
140
|
+
const entry = isPlainObject(targets) ? targets[name] : undefined;
|
|
141
|
+
|
|
142
|
+
if (!isPlainObject(entry)) {
|
|
143
|
+
const declared = isPlainObject(targets) ? Object.keys(targets) : [];
|
|
144
|
+
throw new Error(`No target "${name}" is declared: this brand declares [${declared.join(', ')}]`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return entry;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Where a WEB target is served from: its own `hosting.provider`, else the
|
|
152
|
+
* default `github`.
|
|
153
|
+
* @param {object} config - Composed omega config carrying `targets`.
|
|
154
|
+
* @param {string} name - The target name.
|
|
155
|
+
* @returns {string} A HOSTING_PROVIDERS value.
|
|
156
|
+
* @throws {Error} When the config declares no target of that name.
|
|
77
157
|
*/
|
|
78
|
-
function
|
|
79
|
-
const
|
|
80
|
-
|
|
158
|
+
function hostingProvider(config, name) {
|
|
159
|
+
const entry = targetEntry(config, name);
|
|
160
|
+
const hosting = isPlainObject(entry.hosting) ? entry.hosting : {};
|
|
161
|
+
|
|
162
|
+
return hosting.provider || DEFAULT_HOSTING_PROVIDER;
|
|
81
163
|
}
|
|
82
164
|
|
|
83
165
|
/**
|
|
84
|
-
*
|
|
85
|
-
* the
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* re-derive the merge rules for itself.
|
|
166
|
+
* A web target's own repo: `<brand.id>-<target name>` under the brand's org,
|
|
167
|
+
* holding the BUILT site only (one force-orphan commit on `gh-pages`, served
|
|
168
|
+
* by Pages at the target's url). The source monorepo stays private in a free
|
|
169
|
+
* org this way, which is what a shared `gh-pages` branch on it made impossible.
|
|
89
170
|
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
171
|
+
* Only the target's NAME distinguishes it, per the `<brand.id>-<role>` rule, so
|
|
172
|
+
* a second web target named `community` publishes to `<brand.id>-community`.
|
|
173
|
+
*
|
|
174
|
+
* @param {object} config - Composed omega config carrying `targets`.
|
|
175
|
+
* @param {string} name - The web target's name.
|
|
176
|
+
* @returns {{ owner: string, name: string, slug: string }|null} Null when the config names no org or no brand id, and null when another provider hosts this target (there is no GitHub repo to address then).
|
|
177
|
+
* @throws {Error} When the name is not declared, or names a target that is not web.
|
|
92
178
|
*/
|
|
93
|
-
function
|
|
94
|
-
const
|
|
95
|
-
const name = brandRepoName(config);
|
|
179
|
+
function websiteRepo(config, name) {
|
|
180
|
+
const entry = targetEntry(config, name);
|
|
96
181
|
|
|
97
|
-
|
|
182
|
+
if (entry.type !== 'web') {
|
|
183
|
+
throw new Error(`targets.${name} is a ${entry.type} target: only a web target is served from its own website repo`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (hostingProvider(config, name) !== 'github') return null;
|
|
187
|
+
|
|
188
|
+
return derivedRepo(config, name);
|
|
98
189
|
}
|
|
99
190
|
|
|
100
191
|
/**
|
|
101
|
-
* The
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* the
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
192
|
+
* The GitHub Pages custom domain a web target serves at: the bare host of its
|
|
193
|
+
* `targetUrl`. The ONE derivation of it, asked by the manage walk (which sets
|
|
194
|
+
* the domain on the repo) and by the web deploy (which writes the CNAME file
|
|
195
|
+
* the push publishes) alike, so the two can never claim different domains for
|
|
196
|
+
* one site.
|
|
197
|
+
*
|
|
198
|
+
* A `*.github.io` host is NOT a custom domain
|
|
199
|
+
* ([#366](https://github.com/Omega-JS-Stack/omega/issues/366)): a project
|
|
200
|
+
* site's url names its PAGES address, and reading that as a domain would have
|
|
201
|
+
* the deploy claim `<owner>.github.io` in a CNAME and mount the build at `/`,
|
|
202
|
+
* where every asset 404s.
|
|
203
|
+
*
|
|
204
|
+
* @param {object} config - Composed omega config carrying `brand` and `targets`.
|
|
205
|
+
* @param {string} name - The web target's name.
|
|
206
|
+
* @returns {string} The bare host, or '' when the target has no custom domain (or no url at all).
|
|
110
207
|
*/
|
|
111
|
-
function
|
|
112
|
-
const
|
|
113
|
-
|
|
208
|
+
function pagesHost(config, name) {
|
|
209
|
+
const targets = config && config.targets;
|
|
210
|
+
// A target the config does not declare has no derivable url of its own: a
|
|
211
|
+
// standalone project scaffolded before its first manage walk is the whole
|
|
212
|
+
// site, so the brand's own url is the answer rather than a `<name>.` host
|
|
213
|
+
// invented for a sibling that does not exist.
|
|
214
|
+
const url = isPlainObject(targets) && isPlainObject(targets[name])
|
|
215
|
+
? targetUrl(config, name)
|
|
216
|
+
: (config && config.brand ? config.brand.url : '');
|
|
217
|
+
|
|
218
|
+
const host = brandHost(String(url || ''));
|
|
114
219
|
|
|
115
|
-
return
|
|
220
|
+
return DEFAULT_PAGES_HOST.test(host) ? '' : host;
|
|
116
221
|
}
|
|
117
222
|
|
|
118
223
|
/**
|
|
119
|
-
* The brand's ONE
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* This is the ONE home of that rule. Every reader takes it from here (the site
|
|
127
|
-
* global's download links, @omega.js/desktop's electron-builder publish block,
|
|
128
|
-
* its release-repo provisioning, its finalize-release upload), so the feed a
|
|
129
|
-
* shipped app polls and the URL a download button carries can never disagree.
|
|
130
|
-
*
|
|
131
|
-
* @param {object} config - Composed omega config (raw or desktop-resolved).
|
|
132
|
-
* @returns {{ owner: string, name: string, repo: string }} `repo` is the slug, '' unless BOTH halves resolve (half an address addresses nothing).
|
|
224
|
+
* The brand monorepo's visibility, from the ONE place that states it: the brand
|
|
225
|
+
* root's `package.json` `private` field. `true` or ABSENT is private (every
|
|
226
|
+
* monorepo is private by default, Ian 2026-09-11); only a literal `false` is a
|
|
227
|
+
* public brand. The manage walk reconciles the repo to this in both directions.
|
|
228
|
+
*
|
|
229
|
+
* @param {string} brandRoot - The brand root directory.
|
|
230
|
+
* @returns {string} 'private' | 'public'.
|
|
133
231
|
*/
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
232
|
+
function brandVisibility(brandRoot) {
|
|
233
|
+
let contents;
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
contents = fs.readFileSync(path.join(brandRoot, 'package.json'), 'utf8');
|
|
237
|
+
} catch (e) {
|
|
238
|
+
// A brand with no manifest at all is private like any other: the default is
|
|
239
|
+
// the safe half of the question, and the walk never guesses public. Any
|
|
240
|
+
// OTHER read failure (a permission error, a directory in its place) is this
|
|
241
|
+
// machine being broken, and answering 'private' for it would hide the break
|
|
242
|
+
// behind a plausible answer.
|
|
243
|
+
if (e.code === 'ENOENT') return 'private';
|
|
244
|
+
throw e;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// A manifest that does not parse is a brand nobody can build: it fails here,
|
|
248
|
+
// loudly, rather than reporting a visibility read off a file nothing read.
|
|
249
|
+
const manifest = JSON.parse(contents);
|
|
138
250
|
|
|
139
|
-
return
|
|
251
|
+
return manifest && manifest.private === false ? 'public' : 'private';
|
|
140
252
|
}
|
|
141
253
|
|
|
142
|
-
module.exports = {
|
|
254
|
+
module.exports = {
|
|
255
|
+
REPO_PROVIDERS,
|
|
256
|
+
HOSTING_PROVIDERS,
|
|
257
|
+
repoBlock,
|
|
258
|
+
sourceRepo,
|
|
259
|
+
releasesRepo,
|
|
260
|
+
websiteRepo,
|
|
261
|
+
hostingProvider,
|
|
262
|
+
pagesHost,
|
|
263
|
+
brandVisibility,
|
|
264
|
+
};
|