@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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* chatsy settings: nothing reads that name.
|
|
7
7
|
*
|
|
8
8
|
* Like secrets.js this is a key-NAME test, walked at every depth (shared
|
|
9
|
-
* level, inside a target entry, inside an
|
|
9
|
+
* level, inside a target entry, inside an array item): the rename moved
|
|
10
10
|
* the key, not its home. Only unambiguous renames belong here: a name that
|
|
11
11
|
* still exists as a legitimate key somewhere in the schema (`google`/`meta`
|
|
12
12
|
* under `analytics.providers`) would false-positive and is left to the mapping
|
|
@@ -20,16 +20,33 @@
|
|
|
20
20
|
* name (`slapform` → `forms.providers.slapform`), and folded two keys into
|
|
21
21
|
* `cloud`. A name test can't express those — `slapform` is legitimate again
|
|
22
22
|
* one level down, and `firebase` lives on as `client.firebase` — so these
|
|
23
|
-
* match one EXACT path from the root
|
|
24
|
-
*
|
|
25
|
-
* `github` is deliberately NOT here: the brand's own `github` (content
|
|
26
|
-
* identity, unchanged; a shared key since #277) lives at the top level, and
|
|
27
|
-
* a `targets.backend.github` override is overlaid there too by the resolved
|
|
28
|
-
* view, so a name test would false-positive. Its rename to
|
|
29
|
-
* `repo.providers.github` is carried by the mapping tables in
|
|
30
|
-
* docs/shared/config.md instead.
|
|
23
|
+
* match one EXACT path from the root, with the target NAME read as its TYPE
|
|
24
|
+
* (#886) so a `targets.web.*` row fires on every web target a brand runs.
|
|
31
25
|
*/
|
|
32
26
|
|
|
27
|
+
const { TARGETS, CUSTOM_TARGET_TYPE } = require('./schema.js');
|
|
28
|
+
|
|
29
|
+
// Every legal target `type`, so a per-type row set covers all of them (#883).
|
|
30
|
+
const TARGET_TYPES = [...TARGETS, CUSTOM_TARGET_TYPE];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The `translation.exclude` → `translation.include` move (#858): every route
|
|
34
|
+
* the brand skipped becomes a negation, in the order it was written, on top
|
|
35
|
+
* of `**`. The FRAMEWORK default (`['**', '!blog/**']`) is deliberately not
|
|
36
|
+
* what a carrying brand lands on: it was translating its blog, and a
|
|
37
|
+
* conversion that changed which pages reach a provider would be a behavior
|
|
38
|
+
* change dressed as a rename. Routes are normalized the way the translation
|
|
39
|
+
* pass normalizes them (no leading or trailing slash), so `/changelog/` lands
|
|
40
|
+
* as `!changelog`.
|
|
41
|
+
* @param {*} value - the authored `exclude` list
|
|
42
|
+
* @returns {string[]} the `include` list that means the same thing
|
|
43
|
+
*/
|
|
44
|
+
function excludeToInclude(value) {
|
|
45
|
+
const routes = Array.isArray(value) ? value : [];
|
|
46
|
+
|
|
47
|
+
return ['**', ...routes.map((entry) => `!${String(entry).replace(/^\/+|\/+$/g, '')}`)];
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
// key name → { replacement, why } (docs/shared/config.md carries the rows)
|
|
34
51
|
const RETIRED_KEYS = {
|
|
35
52
|
web_manager: {
|
|
@@ -45,16 +62,16 @@ const RETIRED_KEYS = {
|
|
|
45
62
|
why: 'the banner became a real consent gate (#383) — the block names the DECISION, not the cookie, and its palette/theme/type keys are gone (tokens paint it, the visitor\'s region picks opt-in vs opt-out)',
|
|
46
63
|
},
|
|
47
64
|
|
|
48
|
-
// The web
|
|
65
|
+
// The web TARGET is the subdomain (#588). `brand.subdomains` was read by
|
|
49
66
|
// ONE thing (the cloud hosting op, which ensured an api.{sub}.{domain} per
|
|
50
67
|
// entry) and declared by nothing: no schema rule, no default, never
|
|
51
68
|
// materialized. Ian's 2026-09-01 call gave the fact a real home. A NAME test
|
|
52
69
|
// by the rule above: `subdomains` exists nowhere else in the schema (the
|
|
53
70
|
// legacy searchConsole.subdomains was dropped outright), so the walk catches
|
|
54
|
-
// it at every depth,
|
|
71
|
+
// it at every depth, target entries included.
|
|
55
72
|
subdomains: {
|
|
56
73
|
replacement: 'targets.web',
|
|
57
|
-
why: "each subdomain is
|
|
74
|
+
why: "each subdomain is its own web TARGET (#588/#886): [\"admin\", \"cdn\"] becomes sibling keys beside the main site, `admin: { type: 'web' }, cdn: { type: 'web' }`, where the NAME is the subdomain (https://admin.<brand host>), an entry's own `url` overrides it for a custom host, and the targets share ONE api.<domain>",
|
|
58
75
|
},
|
|
59
76
|
|
|
60
77
|
// The feature is `connections` now (#788, Ian 2026-09-03): a user connection
|
|
@@ -67,6 +84,16 @@ const RETIRED_KEYS = {
|
|
|
67
84
|
replacement: 'connections',
|
|
68
85
|
why: "the product concept is a CONNECTION (#788) — the per-provider block is unchanged, the credentials are the CONNECTIONS_<PROVIDER>_CLIENT_ID/_SECRET env pair now, and a brand's own provider lives at targets/backend/src/connections/<name>.js",
|
|
69
86
|
},
|
|
87
|
+
|
|
88
|
+
// The company block names the parent (#677), so `parent` is retired
|
|
89
|
+
// OUTRIGHT: the topology moved to `company: { id }` first, and the last
|
|
90
|
+
// meaning it carried, the webhook opt-out, is `company: { webhooks: false }`
|
|
91
|
+
// now. A NAME test by the rule above: `parent` exists nowhere else in the
|
|
92
|
+
// schema.
|
|
93
|
+
parent: {
|
|
94
|
+
replacement: 'company.webhooks',
|
|
95
|
+
why: "the company block names the parent (#677): the topology is `company: { id: '<parent brand.id>' }` (or 'self'), and the only other thing `parent` ever said, `false` for \"the provider ACCOUNT is shared and its one account-level webhook is owned elsewhere\", is `company: { webhooks: false }`",
|
|
96
|
+
},
|
|
70
97
|
};
|
|
71
98
|
|
|
72
99
|
// exact dotted path → { replacement, why } (docs/shared/config.md carries the rows)
|
|
@@ -201,7 +228,7 @@ const RETIRED_PATHS = {
|
|
|
201
228
|
},
|
|
202
229
|
'monitoring.dsn': {
|
|
203
230
|
replacement: 'monitoring.providers.sentry.dsn',
|
|
204
|
-
why: 'provider-hung Sentry settings live under the provider that reads them (#425)
|
|
231
|
+
why: 'provider-hung Sentry settings live under the provider that reads them (#425): per-surface DSNs are targets.<name>.monitoring.providers.sentry.dsn',
|
|
205
232
|
},
|
|
206
233
|
'monitoring.environment': {
|
|
207
234
|
replacement: 'monitoring.providers.sentry.environment',
|
|
@@ -310,6 +337,32 @@ const RETIRED_PATHS = {
|
|
|
310
337
|
why: 'two homes for one fact (#610) — the /extension page and its shortlinks read the extension target\'s store listings, curated onto site.targets.extension.listings',
|
|
311
338
|
},
|
|
312
339
|
|
|
340
|
+
// ─── the four schema-less web sections (#850) ─────────────────────────
|
|
341
|
+
// Everything the build processes has a schema home (Ian 2026-09-09). These
|
|
342
|
+
// four were the exception: legacy UJM presentation blocks the converter
|
|
343
|
+
// wrote under `targets.web`, which @omega.js/web carried in a PRIVATE list
|
|
344
|
+
// (`WEB_ONLY_SECTIONS`) purely to let its own `config:` guard pass them.
|
|
345
|
+
// The list is gone, so each one is a registered path instead of a key that
|
|
346
|
+
// validates clean and reaches nothing. Matched at their AUTHORED path, the
|
|
347
|
+
// one place a carrying brand has them (a root spelling on a web load is the
|
|
348
|
+
// same key overlaid, exactly as with the #610 pair above).
|
|
349
|
+
'targets.web.favicon': {
|
|
350
|
+
replacement: 'nothing for the path; brand.images.favicon for the source image',
|
|
351
|
+
why: 'the favicon set is MINTED from the brand images (#850): the manager assets service mints it and the web build bridges it to /assets/images/favicon, so a path override pointed the whole site at an unminted folder; theme-color comes from `brand.color` now, the one place a brand states its hex',
|
|
352
|
+
},
|
|
353
|
+
'targets.web.manifest': {
|
|
354
|
+
replacement: 'nothing: the minted set ships site.webmanifest',
|
|
355
|
+
why: 'no reader anywhere in @omega.js/web (#850): the web app manifest that ships is the minted set\'s own site.webmanifest, so every key under this block was a value nothing consulted',
|
|
356
|
+
},
|
|
357
|
+
'targets.web.icons': {
|
|
358
|
+
replacement: 'the `icon` on the link itself, as Font Awesome classes',
|
|
359
|
+
why: 'one icon mechanism (#619): a footer link carries its own `fa-*` classes (`icon: \'fa-brands fa-github\'`), so the name-to-markup map is gone; the legacy block only ever held a `style`, which the map lookup could never resolve',
|
|
360
|
+
},
|
|
361
|
+
'targets.web.currency': {
|
|
362
|
+
replacement: 'payment.currency',
|
|
363
|
+
why: 'two homes for one fact (#850): the price currency belongs to the payment section every other surface reads it from, and the pricing JSON-LD reads it there',
|
|
364
|
+
},
|
|
365
|
+
|
|
313
366
|
// ─── redirects are not web config (#466) ──────────────────────────────
|
|
314
367
|
// The block shipped for one wave (0.45.0) and was withdrawn: static hosting
|
|
315
368
|
// has no server, so the map could only be answered CLIENT-side off the built
|
|
@@ -378,20 +431,172 @@ const RETIRED_PATHS = {
|
|
|
378
431
|
replacement: 'nothing: the versionless assets live on the `v<x.y.z>` release',
|
|
379
432
|
why: 'one public releases repo per brand (#620/#799): a stable mirror tag is what `/releases/latest/download/<asset>` replaced, so no tag is configured anywhere',
|
|
380
433
|
},
|
|
434
|
+
|
|
435
|
+
// ─── one repo block, and no repo name anywhere (#883) ──────────────────
|
|
436
|
+
// A brand's repo hosting used to be spelled in four places: the
|
|
437
|
+
// `repo.providers.github` block, a separate top-level `github` identity, a
|
|
438
|
+
// `targets.<name>.github.repo` override, and the desktop releases
|
|
439
|
+
// owner/repo. One block says it now (`repo: { provider, org }`), every repo
|
|
440
|
+
// name derives from `<brand.id>-<role>`, and visibility is the brand root
|
|
441
|
+
// package.json's `private` field. Matched at their AUTHORED paths, one row
|
|
442
|
+
// per LEAF: each of these validated clean under the new shape and silently
|
|
443
|
+
// addressed a repo nothing publishes to.
|
|
444
|
+
'repo.providers.github.org': {
|
|
445
|
+
replacement: 'repo.org',
|
|
446
|
+
why: 'ONE repo block (#883): `repo: { provider: \'github\', org }` is the whole declaration, and the org owns every repo the brand derives',
|
|
447
|
+
},
|
|
448
|
+
'repo.providers.github.repo': {
|
|
449
|
+
replacement: 'nothing: the source repo IS `<brand.id>-omega`',
|
|
450
|
+
why: 'no repo NAME is configurable anywhere (#883): a repo name that must differ is a brand id that must differ, so rename the GitHub repo to `<brand.id>-omega` instead',
|
|
451
|
+
},
|
|
452
|
+
'repo.providers.github.private': {
|
|
453
|
+
replacement: 'the brand root package.json `private` field',
|
|
454
|
+
why: 'visibility has ONE statement (#883): `private: true` (or absent) is a private brand, `false` a public one, and the manage walk reconciles the repo to it in both directions',
|
|
455
|
+
},
|
|
456
|
+
'repo.providers.github.shared': {
|
|
457
|
+
replacement: 'nothing: an org may host many brands, and no brand rewrites an org profile',
|
|
458
|
+
why: 'the org-profile reconcile is gone (#883), so there is no shared-org exception left to declare',
|
|
459
|
+
},
|
|
460
|
+
'repo.providers.github.enabled': {
|
|
461
|
+
replacement: 'the presence of the `repo` block',
|
|
462
|
+
why: 'presence is the switch (#883), exactly as a target key\'s presence enables that target: a brand that hosts its source somewhere the manager does not touch omits the block',
|
|
463
|
+
},
|
|
464
|
+
'github.user': {
|
|
465
|
+
replacement: 'nothing: the org is `repo.org`',
|
|
466
|
+
why: 'the separate GitHub identity block is gone (#883): nothing read `user`, and every repo address derives from `repo.org` plus `brand.id`',
|
|
467
|
+
},
|
|
468
|
+
'github.website': {
|
|
469
|
+
replacement: 'nothing: a web target\'s site repo is `<brand.id>-<target name>`',
|
|
470
|
+
why: 'the website repo derives now (#883): each GitHub-hosted web target publishes its built site to its own `<brand.id>-<name>` repo, Pages serving it at the target\'s url',
|
|
471
|
+
},
|
|
472
|
+
// ─── the company is ONE key, outside `brand` (#677) ────────────────────
|
|
473
|
+
// `brand.company` was a typed DISPLAY NAME (Ian 2026-09-12: "brand.company
|
|
474
|
+
// hardcoded was a workaround"): the parent's name is the parent's to state,
|
|
475
|
+
// so it resolves now. Registered at its authored path, because `company` is
|
|
476
|
+
// a legitimate key one level up and at the top level.
|
|
477
|
+
'brand.company': {
|
|
478
|
+
replacement: 'company.name (resolved from `company: { id }`)',
|
|
479
|
+
why: "the company is ONE top-level key now (#677): type `company: { id: '<parent brand.id>' }` (or 'self') and the loader fills company.name/url/images from the parent's own config, so no brand restates its parent's facts",
|
|
480
|
+
},
|
|
481
|
+
'brand.images.companyWordmark': {
|
|
482
|
+
replacement: 'company.images.wordmark (resolved from `company: { id }`)',
|
|
483
|
+
why: "the parent's wordmark is the parent's own `brand.images.wordmark` (#677), resolved through `company: { id }` for every sub-brand instead of pasted into each one",
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
// ─── the ONE platform vocabulary (#867) ───────────────────────────────
|
|
487
|
+
// The client's words everywhere (`mac`, `windows`, `linux`), and what a
|
|
488
|
+
// target ships is DECLARED per format. Both of these validated clean while
|
|
489
|
+
// nothing read them: a brand still saying `win` got @omega.js/desktop's
|
|
490
|
+
// default Windows settings and its own were ignored, and a brand still
|
|
491
|
+
// saying `snap.enabled: true` published no snap at all. Registered at both
|
|
492
|
+
// shapes a brand can write them in: inside the target entry (the brand file)
|
|
493
|
+
// and at the top level (a target's own config/omega.json5).
|
|
494
|
+
'platforms.win': {
|
|
495
|
+
replacement: 'platforms.windows (with its formats inside: platforms.windows.formats.nsis)',
|
|
496
|
+
why: "ONE platform vocabulary, the client's (#867): run `npx omega manage --migration=platform-names --execute` at the brand root to rewrite it (it also renames config/icons/macos/ to config/icons/mac/). Run the migration BEFORE `omega migrate`, which deletes a retired key rather than moving it",
|
|
497
|
+
},
|
|
498
|
+
'targets.desktop.platforms.win': {
|
|
499
|
+
replacement: 'targets.desktop.platforms.windows (with its formats inside: platforms.windows.formats.nsis)',
|
|
500
|
+
why: "ONE platform vocabulary, the client's (#867): run `npx omega manage --migration=platform-names --execute` at the brand root to rewrite it (it also renames config/icons/macos/ to config/icons/mac/). Run the migration BEFORE `omega migrate`, which deletes a retired key rather than moving it",
|
|
501
|
+
},
|
|
502
|
+
'platforms.linux.snap': {
|
|
503
|
+
replacement: 'platforms.linux.formats.snap (presence IS the switch, so the `enabled` flag is gone)',
|
|
504
|
+
why: 'what a target ships is one declaration now (#867): every platform and format defaults ON and `platforms.linux.formats.snap: false` is the only way to drop the snap. Its settings (channels, confinement, grade, autoStart) move inside the format. `npx omega manage --migration=platform-names --execute` performs the move',
|
|
505
|
+
},
|
|
506
|
+
'targets.desktop.platforms.linux.snap': {
|
|
507
|
+
replacement: 'targets.desktop.platforms.linux.formats.snap (presence IS the switch, so the `enabled` flag is gone)',
|
|
508
|
+
why: 'what a target ships is one declaration now (#867): every platform and format defaults ON and `platforms.linux.formats.snap: false` is the only way to drop the snap. Its settings (channels, confinement, grade, autoStart) move inside the format. `npx omega manage --migration=platform-names --execute` performs the move',
|
|
509
|
+
},
|
|
510
|
+
|
|
511
|
+
// ─── the translation list says what to TRANSLATE (#858) ───────────────
|
|
512
|
+
// Ian 2026-09-13: an exclude list defaulted to "translate everything", so a
|
|
513
|
+
// brand that never thought about it paid a provider for its whole blog. The
|
|
514
|
+
// list is `translation.include` now: globs with `!` negation, defaulting to
|
|
515
|
+
// ['**', '!blog/**'] in the DEFAULTS layer, and the page half is the same
|
|
516
|
+
// key one level down (`translation.include: true`/`false` in frontmatter),
|
|
517
|
+
// which is Ian's 2026-09-09 same-name ruling. The row carries a `convert`,
|
|
518
|
+
// so `omega migrate` MOVES the setting instead of only deleting it: each
|
|
519
|
+
// excluded route becomes a negation on top of the default. Registered at its
|
|
520
|
+
// authored path AND at the `targets.web` overlay, the two places a brand can
|
|
521
|
+
// write it; `translation` is a legitimate key name at both.
|
|
522
|
+
'translation.exclude': {
|
|
523
|
+
replacement: 'translation.include',
|
|
524
|
+
why: "the route list says what to TRANSLATE now (#858, Ian 2026-09-13): globs with `!` negation, read in .gitignore order, defaulting to ['**', '!blog/**'], so `exclude: ['docs']` becomes `include: ['**', '!docs']`, and a page overrides it for itself with `translation.include: true`/`false` in its own frontmatter. `omega migrate` performs the move",
|
|
525
|
+
convert: excludeToInclude,
|
|
526
|
+
},
|
|
527
|
+
'targets.web.translation.exclude': {
|
|
528
|
+
replacement: 'targets.web.translation.include',
|
|
529
|
+
why: "the route list says what to TRANSLATE now (#858, Ian 2026-09-13): globs with `!` negation, read in .gitignore order, defaulting to ['**', '!blog/**'], so `exclude: ['docs']` becomes `include: ['**', '!docs']`, and a page overrides it for itself with `translation.include: true`/`false` in its own frontmatter. `omega migrate` performs the move",
|
|
530
|
+
convert: excludeToInclude,
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
'targets.desktop.releases.owner': {
|
|
534
|
+
replacement: 'nothing: the releases repo is `<brand.id>-releases` under `repo.org`',
|
|
535
|
+
why: 'one public releases repo per brand (#883), with no override: `releases: {}` stays the presence switch for the site\'s download links',
|
|
536
|
+
},
|
|
537
|
+
'targets.desktop.releases.repo': {
|
|
538
|
+
replacement: 'nothing: the releases repo is `<brand.id>-releases` under `repo.org`',
|
|
539
|
+
why: 'one public releases repo per brand (#883), with no override: `releases: {}` stays the presence switch for the site\'s download links',
|
|
540
|
+
},
|
|
381
541
|
};
|
|
382
542
|
|
|
383
|
-
//
|
|
384
|
-
// (
|
|
385
|
-
//
|
|
386
|
-
//
|
|
387
|
-
//
|
|
388
|
-
|
|
389
|
-
|
|
543
|
+
// The per-target `github` override, one row per TYPE (#883). The type-row rule
|
|
544
|
+
// above (shapePath reads a target's NAME as its TYPE) makes each row fire on
|
|
545
|
+
// every target of that type a brand runs, and enumerating TARGET_TYPES is what
|
|
546
|
+
// keeps a type nobody thought of from slipping through: the backend's CMS
|
|
547
|
+
// content repo is the override that existed, but the key validated clean on any
|
|
548
|
+
// target and pointed the commits at a repo nothing else addressed.
|
|
549
|
+
for (const type of TARGET_TYPES) {
|
|
550
|
+
RETIRED_PATHS[`targets.${type}.github.repo`] = {
|
|
551
|
+
replacement: 'nothing: every repo the brand owns is `<brand.id>-<role>` under `repo.org`',
|
|
552
|
+
why: 'no repo NAME is configurable anywhere (#883): the CMS commits to the SOURCE repo `<brand.id>-omega`, so a content repo of its own is a brand of its own',
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// The walked path is not always the SHAPE a RETIRED_PATHS row names, two ways:
|
|
557
|
+
// a value inside an array carries its position (`redirects.0.from`), and a
|
|
558
|
+
// target carries its NAME while the rows name its TYPE (#886). Both are
|
|
559
|
+
// normalized for MATCHING only: the REPORTED path stays the real one, which is
|
|
560
|
+
// where the author finds the key.
|
|
561
|
+
//
|
|
562
|
+
// The name normalization is what makes a `targets.web.*` row fire on EVERY web
|
|
563
|
+
// target a brand runs (`targets.community.meta.title` when community is
|
|
564
|
+
// `type: 'web'`), which is the shape a brand with two sites has (#732, #886).
|
|
565
|
+
function shapePath(keyPath, targetTypes) {
|
|
566
|
+
const parts = keyPath.split('.').filter((segment) => !/^\d+$/.test(segment));
|
|
567
|
+
|
|
568
|
+
if (parts[0] === 'targets' && parts.length > 1 && targetTypes[parts[1]]) {
|
|
569
|
+
parts[1] = targetTypes[parts[1]];
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return parts.join('.');
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Every declared target's name → type, read off the config being walked. A
|
|
577
|
+
* sub-tree with no `targets` map (or entries with no `type`) yields {}, so the
|
|
578
|
+
* rows then match by the key as written.
|
|
579
|
+
* @param {object} object - Parsed config (or any sub-tree of one).
|
|
580
|
+
* @returns {object} name → type.
|
|
581
|
+
*/
|
|
582
|
+
function targetTypes(object) {
|
|
583
|
+
const targets = object && object.targets;
|
|
584
|
+
if (!targets || typeof targets !== 'object' || Array.isArray(targets)) return {};
|
|
585
|
+
|
|
586
|
+
const types = {};
|
|
587
|
+
Object.keys(targets).forEach((name) => {
|
|
588
|
+
const entry = targets[name];
|
|
589
|
+
if (entry && typeof entry === 'object' && !Array.isArray(entry) && typeof entry.type === 'string') {
|
|
590
|
+
types[name] = entry.type;
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
return types;
|
|
390
595
|
}
|
|
391
596
|
|
|
392
|
-
function walk(node, path, found) {
|
|
597
|
+
function walk(node, path, found, types) {
|
|
393
598
|
if (Array.isArray(node)) {
|
|
394
|
-
node.forEach((item, index) => walk(item, path ? `${path}.${index}` : String(index), found));
|
|
599
|
+
node.forEach((item, index) => walk(item, path ? `${path}.${index}` : String(index), found, types));
|
|
395
600
|
return;
|
|
396
601
|
}
|
|
397
602
|
|
|
@@ -406,13 +611,13 @@ function walk(node, path, found) {
|
|
|
406
611
|
found.push({ path: keyPath, key, ...RETIRED_KEYS[key] });
|
|
407
612
|
}
|
|
408
613
|
|
|
409
|
-
const
|
|
614
|
+
const shape = shapePath(keyPath, types);
|
|
410
615
|
|
|
411
|
-
if (RETIRED_PATHS[
|
|
412
|
-
found.push({ path: keyPath, key, ...RETIRED_PATHS[
|
|
616
|
+
if (RETIRED_PATHS[shape]) {
|
|
617
|
+
found.push({ path: keyPath, key, ...RETIRED_PATHS[shape] });
|
|
413
618
|
}
|
|
414
619
|
|
|
415
|
-
walk(node[key], keyPath, found);
|
|
620
|
+
walk(node[key], keyPath, found, types);
|
|
416
621
|
});
|
|
417
622
|
}
|
|
418
623
|
|
|
@@ -423,7 +628,7 @@ function walk(node, path, found) {
|
|
|
423
628
|
*/
|
|
424
629
|
function findRetiredKeys(object) {
|
|
425
630
|
const found = [];
|
|
426
|
-
walk(object, '', found);
|
|
631
|
+
walk(object, '', found, targetTypes(object));
|
|
427
632
|
return found;
|
|
428
633
|
}
|
|
429
634
|
|