@omega.js/desktop 0.52.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -48
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli-run.js +4 -1
- package/dist/cli.js +3 -3
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/cdp.js +1 -1
- package/dist/commands/clean.js +4 -5
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/dev.js +25 -0
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +18 -23
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +4 -4
- package/dist/commands/runner.js +11 -11
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +8 -8
- package/dist/commands/update.js +7 -6
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +18 -18
- package/dist/defaults/_.gitignore +0 -2
- package/dist/defaults/_mas/README.md +3 -3
- package/dist/defaults/config/certs/README.md +1 -1
- package/dist/defaults/config/omega.json5 +43 -43
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +2 -2
- package/dist/defaults/hooks/build/pre.js +2 -2
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +2 -2
- package/dist/defaults/hooks/release/pre.js +2 -2
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
- package/dist/defaults/src/integrations/context-menu/index.js +13 -13
- package/dist/defaults/src/integrations/menu/index.js +8 -8
- package/dist/defaults/src/integrations/tray/index.js +12 -12
- package/dist/defaults/src/main.js +5 -7
- package/dist/defaults/src/preload.js +4 -6
- package/dist/defaults/test/README.md +5 -5
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +11 -14
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +29 -29
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +399 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +21 -8
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +30 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +21 -7
- package/dist/test/suites/build/deploy-direct.test.js +7 -5
- package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
- package/dist/test/suites/build/deploy-hook.test.js +7 -5
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +13 -5
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +7 -7
- package/dist/test/suites/build/migrate.test.js +29 -0
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +11 -10
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +15 -4
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +28 -8
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/runner-env.js +13 -28
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/company.js +46 -14
- package/dist/vendor/config/defaults.js +30 -7
- package/dist/vendor/config/edit.js +25 -3
- package/dist/vendor/config/env-delivery.js +1 -1
- package/dist/vendor/config/env-schema.js +3 -6
- package/dist/vendor/config/env.js +34 -22
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +21 -28
- package/dist/vendor/config/load.js +16 -9
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +10 -27
- package/dist/vendor/config/schema-client.js +64 -0
- package/dist/vendor/config/schema-cloud.js +38 -0
- package/dist/vendor/config/schema-manager.js +118 -0
- package/dist/vendor/config/schema-overrides.js +68 -0
- package/dist/vendor/config/schema.js +104 -160
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +97 -78
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +16 -2
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +16 -11
- package/dist/vendor/devkit/defaults-engine.js +15 -51
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +64 -10
- package/dist/vendor/devkit/lockfile.js +32 -13
- package/dist/vendor/devkit/logger.js +7 -2
- package/dist/vendor/devkit/merge-line-files.js +219 -177
- package/dist/vendor/devkit/omega-bin.js +208 -111
- package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
- package/dist/vendor/devkit/preludes/index.js +1 -0
- package/dist/vendor/devkit/target-picker.js +45 -0
- package/dist/vendor/devkit/test/dashed-files.js +37 -0
- package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/devkit/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/package.json +19 -26
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -110
- package/dist/defaults/CLAUDE.md +0 -1
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
- package/dist/vendor/config/env-retired.js +0 -137
- package/dist/vendor/config/retired-keys.js +0 -635
- package/docs/analytics.md +0 -140
- package/docs/app-state.md +0 -92
- package/docs/audit.md +0 -69
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -39
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- package/docs/client-bridge.md +0 -269
- package/docs/common-mistakes.md +0 -21
- package/docs/config-schema.md +0 -120
- package/docs/context-menu.md +0 -112
- package/docs/context.md +0 -81
- package/docs/css.md +0 -90
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -107
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -317
- package/docs/installer-options.md +0 -165
- package/docs/ipc.md +0 -61
- package/docs/lib-modules.md +0 -53
- package/docs/logging.md +0 -229
- package/docs/menu.md +0 -160
- package/docs/releasing.md +0 -239
- package/docs/remote-config.md +0 -118
- package/docs/remote-scripts.md +0 -144
- package/docs/restart-manager.md +0 -144
- package/docs/runner.md +0 -290
- package/docs/sentry.md +0 -97
- package/docs/shared/agent-docs.md +0 -89
- package/docs/shared/analytics.md +0 -612
- package/docs/shared/brands.md +0 -57
- package/docs/shared/breaking-changes.md +0 -851
- package/docs/shared/config.md +0 -1952
- package/docs/shared/deploys.md +0 -341
- package/docs/shared/icons.md +0 -219
- package/docs/shared/local-dev.md +0 -167
- package/docs/shared/logging.md +0 -205
- package/docs/shared/monitoring.md +0 -167
- package/docs/shared/publishing.md +0 -187
- package/docs/shared/rulings.md +0 -34
- package/docs/shared/testing.md +0 -147
- package/docs/shared/theming.md +0 -629
- package/docs/shared/translation.md +0 -333
- package/docs/shared/updates.md +0 -61
- package/docs/signing.md +0 -293
- package/docs/startup.md +0 -142
- package/docs/storage.md +0 -59
- package/docs/templating.md +0 -101
- package/docs/test-boot-layer.md +0 -157
- package/docs/test-framework.md +0 -362
- package/docs/themes.md +0 -149
- package/docs/tooltips.md +0 -99
- package/docs/tray.md +0 -164
- package/docs/usage.md +0 -58
- package/docs/verts.md +0 -62
- package/docs/windows.md +0 -149
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Canonical schema for config/omega.json5 — pure data, no logic.
|
|
3
3
|
*
|
|
4
|
-
* Entry format
|
|
4
|
+
* Entry format:
|
|
5
5
|
*
|
|
6
6
|
* {
|
|
7
7
|
* path: 'brand.id', // dot-path into the RESOLVED config
|
|
@@ -61,11 +61,15 @@
|
|
|
61
61
|
* target entry overrides the shared value.
|
|
62
62
|
*
|
|
63
63
|
* SHARED_SCHEMA always applies; TARGET_SCHEMAS[target] adds that target's
|
|
64
|
-
* refinements
|
|
65
|
-
* entries come from EM's schema (desktop) and the sandbox brand's real @omega.js/backend
|
|
66
|
-
* config (backend), never from guesses.
|
|
64
|
+
* refinements, seeded from real brand configs, never from guesses.
|
|
67
65
|
*/
|
|
68
66
|
|
|
67
|
+
// Rule sets kept in their own files, one concern each.
|
|
68
|
+
const { MANAGER_RULES } = require('./schema-manager.js');
|
|
69
|
+
const { CLIENT_RULES } = require('./schema-client.js');
|
|
70
|
+
const { CLOUD_CONFIG_RULES } = require('./schema-cloud.js');
|
|
71
|
+
const { OVERRIDE_RULES } = require('./schema-overrides.js');
|
|
72
|
+
|
|
69
73
|
// The durations a winback coupon can be built for on every provider that
|
|
70
74
|
// supports the offer (#268). Stripe's third option ('repeating') needs a
|
|
71
75
|
// duration_in_months beside it, which is provider surface nothing here asks
|
|
@@ -203,13 +207,14 @@ const CLIENT_SECTIONS = {
|
|
|
203
207
|
const BRAND_ID_PATTERN = /^[a-z][a-z0-9+\-.]*$/;
|
|
204
208
|
|
|
205
209
|
const SHARED_SCHEMA = [
|
|
210
|
+
...MANAGER_RULES,
|
|
206
211
|
// ── the target's own url ─────────────────────────────────────────────────
|
|
207
212
|
{
|
|
208
213
|
path: 'url',
|
|
209
214
|
type: 'string',
|
|
210
215
|
required: false,
|
|
211
216
|
match: /^https?:\/\//,
|
|
212
|
-
description: "This TARGET's own public URL, and the one key a target entry may set at the top level. A target whose name is not its type derives it from the name (`admin: { type: 'web' }` → https://admin.<host of brand.url
|
|
217
|
+
description: "This TARGET's own public URL, and the one key a target entry may set at the top level. A target whose name is not its type derives it from the name (`admin: { type: 'web' }` → https://admin.<host of brand.url>; docs/shared/config.md → Targets); an entry's own `url` overrides it for a custom host. `brand.url` stays the BRAND's url, which is what brand-level facts (authDomain, the persona domain) read.",
|
|
213
218
|
},
|
|
214
219
|
|
|
215
220
|
// ── the target's own type (#886) ─────────────────────────────────────────
|
|
@@ -222,7 +227,7 @@ const SHARED_SCHEMA = [
|
|
|
222
227
|
type: 'string',
|
|
223
228
|
required: false,
|
|
224
229
|
enum: [...TARGETS, CUSTOM_TARGET_TYPE],
|
|
225
|
-
description: "The FRAMEWORK that runs this target
|
|
230
|
+
description: "The FRAMEWORK that runs this target, or `custom` for a target no framework owns. Key presence in `targets` enables a target by NAME, and this is what says which code runs there, so a target named `admin` with `type: 'web'` is a web build. A resolved target config carries it at the top level like every other key in the entry.",
|
|
226
231
|
},
|
|
227
232
|
|
|
228
233
|
// ── brand ────────────────────────────────────────────────────────────────
|
|
@@ -262,7 +267,7 @@ const SHARED_SCHEMA = [
|
|
|
262
267
|
path: 'brand.type',
|
|
263
268
|
type: 'string',
|
|
264
269
|
required: false,
|
|
265
|
-
description: "The brand's schema.org type ('Organization', 'Corporation', 'LocalBusiness'). @omega.js/web stamps it on the JSON-LD brand node and every @id that cross-references it; unset renders the framework default 'Organization'
|
|
270
|
+
description: "The brand's schema.org type ('Organization', 'Corporation', 'LocalBusiness'). @omega.js/web stamps it on the JSON-LD brand node and every @id that cross-references it; unset renders the framework default 'Organization'.",
|
|
266
271
|
},
|
|
267
272
|
{
|
|
268
273
|
path: 'brand.font',
|
|
@@ -287,7 +292,7 @@ const SHARED_SCHEMA = [
|
|
|
287
292
|
path: 'brand.contact.person.name',
|
|
288
293
|
type: 'string',
|
|
289
294
|
required: false,
|
|
290
|
-
description: 'The human who signs "personal" emails, as it should read ("Jane Doe, CEO"). Required only when something sends a personal-signoff email
|
|
295
|
+
description: 'The human who signs "personal" emails, as it should read ("Jane Doe, CEO"). Required only when something sends a personal-signoff email; that path fails loudly rather than substituting a framework identity.',
|
|
291
296
|
},
|
|
292
297
|
{
|
|
293
298
|
path: 'brand.contact.person.firstName',
|
|
@@ -331,7 +336,7 @@ const SHARED_SCHEMA = [
|
|
|
331
336
|
type: 'string',
|
|
332
337
|
required: false,
|
|
333
338
|
match: /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,
|
|
334
|
-
description:
|
|
339
|
+
description: "Brand accent color as a hex string, #RGB or #RRGGBB. @omega.js/web composes the --omega-accent ramps (light + dark) from it; unset leaves the theme's neutral placeholder standing.",
|
|
335
340
|
},
|
|
336
341
|
{
|
|
337
342
|
path: 'brand.images',
|
|
@@ -345,7 +350,7 @@ const SHARED_SCHEMA = [
|
|
|
345
350
|
path: 'socials',
|
|
346
351
|
type: 'object',
|
|
347
352
|
required: false,
|
|
348
|
-
description: "Platform → handle ({ twitter: 'somiibo' }). The handle derives the profile URL every surface reads (JSON-LD sameAs, the footer row, omega_social), and @omega.js/web emits a redirect shortlink page at /<platform> for each entry
|
|
353
|
+
description: "Platform → handle ({ twitter: 'somiibo' }). The handle derives the profile URL every surface reads (JSON-LD sameAs, the footer row, omega_social), and @omega.js/web emits a redirect shortlink page at /<platform> for each entry. An entry that redirects somewhere OTHER than its profile URL takes the object form { handle, redirect }: the redirect target wins for the shortlink, the handle still names the profile.",
|
|
349
354
|
},
|
|
350
355
|
|
|
351
356
|
// ── cloud (role: app/cloud platform; D12 provider-discriminated) ─────────
|
|
@@ -354,25 +359,14 @@ const SHARED_SCHEMA = [
|
|
|
354
359
|
type: 'string',
|
|
355
360
|
required: false,
|
|
356
361
|
enum: ['firebase'],
|
|
357
|
-
description: "App/cloud platform provider. Only 'firebase' today
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
path: 'cloud.config',
|
|
361
|
-
type: 'object',
|
|
362
|
-
required: false,
|
|
363
|
-
description: 'Provider app config. For firebase: the web-app config verbatim from the console. Public by design — the web API key is not a secret.',
|
|
364
|
-
},
|
|
365
|
-
{
|
|
366
|
-
path: 'cloud.config.projectId',
|
|
367
|
-
type: 'string',
|
|
368
|
-
required: false,
|
|
369
|
-
description: 'Drives auth, emulator project selection, analytics uuidv5 namespace, remote-config URL fallbacks.',
|
|
362
|
+
description: "App/cloud platform provider. Only 'firebase' today; the discriminator exists so a second provider slots in without a key rename.",
|
|
370
363
|
},
|
|
364
|
+
...CLOUD_CONFIG_RULES,
|
|
371
365
|
{
|
|
372
366
|
path: 'cloud.messaging.vapidKey',
|
|
373
367
|
type: 'string',
|
|
374
368
|
required: false,
|
|
375
|
-
description: 'Web-push VAPID public key (Firebase console → Cloud Messaging → Web Push certificates). Public by design
|
|
369
|
+
description: 'Web-push VAPID public key (Firebase console → Cloud Messaging → Web Push certificates). Public by design: it ships to every browser, and the private half stays in the console.',
|
|
376
370
|
},
|
|
377
371
|
{
|
|
378
372
|
path: 'cloud.shared',
|
|
@@ -386,19 +380,19 @@ const SHARED_SCHEMA = [
|
|
|
386
380
|
type: 'string',
|
|
387
381
|
required: false,
|
|
388
382
|
match: /@/,
|
|
389
|
-
description: "OAuth consent screen support email. Defaults to the AUTHORIZING user's email
|
|
383
|
+
description: "OAuth consent screen support email. Defaults to the AUTHORIZING user's email, because the provider rejects any address the caller doesn't own; set only for an owned Google Group.",
|
|
390
384
|
},
|
|
391
385
|
{
|
|
392
386
|
path: 'cloud.oauthRedirectsConfigured',
|
|
393
387
|
type: 'boolean',
|
|
394
388
|
required: false,
|
|
395
|
-
description: "true = the Google OAuth client's authorized origins + redirect URIs are configured by hand. The ONE reconcile flag config keeps
|
|
389
|
+
description: "true = the Google OAuth client's authorized origins + redirect URIs are configured by hand. The ONE reconcile flag config keeps: that surface has no API to re-check, so the cloud service asks once, writes the answer back here, and every later run trusts it. Never set it without doing the work: the confirm is the only proof there is.",
|
|
396
390
|
},
|
|
397
391
|
{
|
|
398
392
|
path: 'cloud.consentAudience',
|
|
399
393
|
type: 'boolean',
|
|
400
394
|
required: false,
|
|
401
|
-
description: "false = stop asking about the OAuth consent screen's audience.
|
|
395
|
+
description: "false = stop asking about the OAuth consent screen's audience. A tri-state opt-out: Google gives NO API write for the audience, so an Internal screen (Error 403: org_internal for every non-org account) is a manage-time stopper that opens the console page and polls; `false` records the deliberate choice to live with an org-only sign-in, and only the cloud service's audience step goes quiet.",
|
|
402
396
|
},
|
|
403
397
|
{
|
|
404
398
|
path: 'cloud.apiSubdomain',
|
|
@@ -411,13 +405,13 @@ const SHARED_SCHEMA = [
|
|
|
411
405
|
path: 'cloud.organizationId',
|
|
412
406
|
type: 'string|boolean',
|
|
413
407
|
required: false,
|
|
414
|
-
description: 'Cloud organization ID the project is created inside
|
|
408
|
+
description: 'Cloud organization ID the project is created inside, a tri-state: unset = ask at project create, false = no org (standalone), value = create inside it.',
|
|
415
409
|
},
|
|
416
410
|
{
|
|
417
411
|
path: 'cloud.billingAccount',
|
|
418
412
|
type: 'string|boolean',
|
|
419
413
|
required: false,
|
|
420
|
-
description: "Billing account ('billingAccounts/XXXXXX-XXXXXX-XXXXXX')
|
|
414
|
+
description: "Billing account ('billingAccounts/XXXXXX-XXXXXX-XXXXXX'), a tri-state: unset = ask, false = stay on the free tier, value = auto-upgrade.",
|
|
421
415
|
},
|
|
422
416
|
|
|
423
417
|
// ── analytics ────────────────────────────────────────────────────────────
|
|
@@ -432,13 +426,13 @@ const SHARED_SCHEMA = [
|
|
|
432
426
|
path: 'analytics.providers.google.propertyId',
|
|
433
427
|
type: 'string',
|
|
434
428
|
required: false,
|
|
435
|
-
description:
|
|
429
|
+
description: "GA4 property id (digits, as the Admin API returns it). The manager's analytics service reconciles the brand's data streams and the Firebase link against it, and it gates the whole google half: no propertyId, no google operations. Interactive setup selects/creates the property and writes it back here.",
|
|
436
430
|
},
|
|
437
431
|
{
|
|
438
432
|
path: 'analytics.providers.google.accountId',
|
|
439
433
|
type: 'string',
|
|
440
434
|
required: false,
|
|
441
|
-
description: "GA account id the property lives under (digits)
|
|
435
|
+
description: "GA account id the property lives under (digits), read by the analytics property picker and the console bookmarks. A company-managed brand inherits the COMPANY layer's value through the merge chain; a brand-level value always wins.",
|
|
442
436
|
},
|
|
443
437
|
{
|
|
444
438
|
path: 'analytics.providers.meta.id',
|
|
@@ -450,7 +444,7 @@ const SHARED_SCHEMA = [
|
|
|
450
444
|
path: 'analytics.providers.meta.accountId',
|
|
451
445
|
type: 'string',
|
|
452
446
|
required: false,
|
|
453
|
-
description: "Meta AD ACCOUNT id ('act_…' or the bare digits) the pixel is created on and found by name against. A non-secret platform id, so it lives here beside google.accountId
|
|
447
|
+
description: "Meta AD ACCOUNT id ('act_…' or the bare digits) the pixel is created on and found by name against. A non-secret platform id, so it lives here beside google.accountId; the token that reaches the account stays in .env (META_ACCESS_TOKEN).",
|
|
454
448
|
},
|
|
455
449
|
{
|
|
456
450
|
path: 'analytics.providers.tiktok.id',
|
|
@@ -468,7 +462,7 @@ const SHARED_SCHEMA = [
|
|
|
468
462
|
path: 'analytics.providers.tiktok.appId',
|
|
469
463
|
type: 'string',
|
|
470
464
|
required: false,
|
|
471
|
-
description:
|
|
465
|
+
description: 'TikTok DEVELOPER APP id the access-token mint authorizes through. Public config, so the manager can walk the portal without asking twice; setup writes it back here. The app secret is pasted once and never saved, and the token lands in .env (TIKTOK_ACCESS_TOKEN).',
|
|
472
466
|
},
|
|
473
467
|
|
|
474
468
|
// ── advertising ──────────────────────────────────────────────────────────
|
|
@@ -476,7 +470,7 @@ const SHARED_SCHEMA = [
|
|
|
476
470
|
path: 'advertising.providers.adsense.client',
|
|
477
471
|
type: 'string',
|
|
478
472
|
required: false,
|
|
479
|
-
description: 'AdSense publisher client id (ca-pub-…). The ONE adsense switch
|
|
473
|
+
description: 'AdSense publisher client id (ca-pub-…). The ONE adsense switch, presence-driven: set it and the manager service manages the account, the site renders units from it and ads.txt carries the record; leave it out and none of that happens. No second gate exists, so a managed-but-ad-free brand is deliberately inexpressible.',
|
|
480
474
|
},
|
|
481
475
|
{
|
|
482
476
|
path: 'advertising.providers.adsense.displaySlot',
|
|
@@ -512,13 +506,13 @@ const SHARED_SCHEMA = [
|
|
|
512
506
|
path: 'advertising.fallback',
|
|
513
507
|
type: 'string|boolean',
|
|
514
508
|
required: false,
|
|
515
|
-
description: "The role a provider miss falls through to
|
|
509
|
+
description: "The role a provider miss falls through to: 'inhouse' renders the house unit, false (or absent) ends the ladder at the built-in promo. Role-level, beside `providers` (docs/web/ads-system.md).",
|
|
516
510
|
},
|
|
517
511
|
{
|
|
518
512
|
path: 'advertising.tags',
|
|
519
513
|
type: 'array',
|
|
520
514
|
required: false,
|
|
521
|
-
description: "This brand's contextual tags (['music', 'audio-tools'])
|
|
515
|
+
description: "This brand's contextual tags (['music', 'audio-tools']), the targeting match input a house unit sends with its serve request unless the include passes its own. No user tracking.",
|
|
522
516
|
},
|
|
523
517
|
|
|
524
518
|
// ── company (ONE typed key, the rest RESOLVED) ───────────────────────────
|
|
@@ -545,7 +539,7 @@ const SHARED_SCHEMA = [
|
|
|
545
539
|
// would be noise, and the fact belongs to the brands that actually share
|
|
546
540
|
// somebody else's provider account.
|
|
547
541
|
materialize: false,
|
|
548
|
-
description: "Whether the manage walk may repoint this company's provider ACCOUNT webhooks
|
|
542
|
+
description: "Whether the manage walk may repoint this company's provider ACCOUNT webhooks. `false` says the SendGrid Event Webhook and the Beehiiv webhook belong to someone else (a shared account whose one account-level webhook points at their production), so the campaigns and newsletter services leave them alone.",
|
|
549
543
|
},
|
|
550
544
|
|
|
551
545
|
// ── features (the catalog every product prices) ──────────────────────────
|
|
@@ -553,7 +547,7 @@ const SHARED_SCHEMA = [
|
|
|
553
547
|
path: 'features',
|
|
554
548
|
type: 'object',
|
|
555
549
|
required: false,
|
|
556
|
-
description: "The feature catalog
|
|
550
|
+
description: "The feature catalog: every feature DEFINED once, keyed by id, in the order every surface renders it. An entry carries name, icon (the full Font Awesome class string) and definition, plus, when the feature is METERED, a `usage` block ({ pace: 'daily' | false, mirror: ['<doc kind>'] }); an entry without one is a perk. Products name only the VALUE (payment.products[].features). Key order is row order on the pricing page and the account's usage bars.",
|
|
557
551
|
},
|
|
558
552
|
|
|
559
553
|
// ── payment (role: billing; provider-discriminated) ──────────────────────
|
|
@@ -562,7 +556,7 @@ const SHARED_SCHEMA = [
|
|
|
562
556
|
type: 'string',
|
|
563
557
|
required: false,
|
|
564
558
|
default: 'USD',
|
|
565
|
-
description: "The ISO 4217 code every price in payment.products is quoted in
|
|
559
|
+
description: "The ISO 4217 code every price in payment.products is quoted in. One currency per brand, named wherever a price is shown or recorded: the pricing page's JSON-LD, the checkout, and the backend's order history (GET /user/orders). Defaults to 'USD'.",
|
|
566
560
|
},
|
|
567
561
|
{
|
|
568
562
|
path: 'payment.providers.stripe.publishableKey',
|
|
@@ -588,20 +582,20 @@ const SHARED_SCHEMA = [
|
|
|
588
582
|
type: 'boolean',
|
|
589
583
|
required: false,
|
|
590
584
|
default: false,
|
|
591
|
-
description:
|
|
585
|
+
description: 'Coinbase Commerce (crypto) checkout, one-time purchases only. Its ONLY credential is a secret (COINBASE_COMMERCE_API_KEY), so there is no public datum to gate on: this is the switch, default OFF, because an accidental ON shows a Crypto button no key can complete.',
|
|
592
586
|
},
|
|
593
587
|
{
|
|
594
588
|
path: 'payment.products',
|
|
595
589
|
type: 'array',
|
|
596
590
|
required: false,
|
|
597
|
-
description: 'Product catalog (@omega.js/backend-shaped: id, name, type, prices, per-provider IDs)
|
|
591
|
+
description: 'Product catalog (@omega.js/backend-shaped: id, name, type, prices, per-provider IDs), referenceable from every target and the ONLY pricing-page source. Optional presentation fields: tagline, popular, enterprise (the talk-to-us tier: its own full-width row, never a card), hidden (still created on every provider and purchasable by id, as QA tiers and grandfathered plans are, but never rendered on the pricing page), url, and features { <catalog id>: value }, a number on a counted feature (the MONTHLY limit, -1 unlimited) or true/false/a string on a perk.',
|
|
598
592
|
},
|
|
599
593
|
{
|
|
600
594
|
path: 'payment.winback.enabled',
|
|
601
595
|
type: 'boolean',
|
|
602
596
|
required: false,
|
|
603
597
|
default: true,
|
|
604
|
-
description: 'The cancel-flow save offer
|
|
598
|
+
description: 'The cancel-flow save offer, shown before the cancellation questionnaire. Defaults ON; false is the whole off switch, and the cancel flow goes straight to the questionnaire.',
|
|
605
599
|
},
|
|
606
600
|
{
|
|
607
601
|
path: 'payment.winback.percent',
|
|
@@ -640,7 +634,7 @@ const SHARED_SCHEMA = [
|
|
|
640
634
|
path: 'monitoring.providers.sentry.org',
|
|
641
635
|
type: 'string',
|
|
642
636
|
required: false,
|
|
643
|
-
description: 'Sentry organization slug (public). Auto-detected when the auth token sees exactly one org
|
|
637
|
+
description: 'Sentry organization slug (public). Auto-detected when the auth token sees exactly one org; the monitoring service writes it back here.',
|
|
644
638
|
},
|
|
645
639
|
{
|
|
646
640
|
path: 'monitoring.providers.sentry.dsn',
|
|
@@ -677,7 +671,7 @@ const SHARED_SCHEMA = [
|
|
|
677
671
|
required: false,
|
|
678
672
|
min: 0,
|
|
679
673
|
max: 1,
|
|
680
|
-
description: 'Browser only: fraction of SESSIONS recorded as a replay, 0..1. Defaults to 0
|
|
674
|
+
description: 'Browser only: fraction of SESSIONS recorded as a replay, 0..1. Defaults to 0, because replay costs bandwidth and captures the DOM, so it is strictly opt-in; any value above 0 loads the replay integration.',
|
|
681
675
|
},
|
|
682
676
|
{
|
|
683
677
|
path: 'monitoring.providers.sentry.replaysOnErrorSampleRate',
|
|
@@ -703,7 +697,7 @@ const SHARED_SCHEMA = [
|
|
|
703
697
|
path: 'monitoring.providers.sentry.bundlePatterns',
|
|
704
698
|
type: 'array',
|
|
705
699
|
required: false,
|
|
706
|
-
description: "Browser only: the URL fragments that identify OUR bundles
|
|
700
|
+
description: "Browser only: the URL fragments that identify OUR bundles; a browser event reports only when a stack frame matches one. Defaults to ['/assets/js/'], where both @omega.js/web and @omega.js/extension serve every framework bundle.",
|
|
707
701
|
},
|
|
708
702
|
|
|
709
703
|
// ── connections ──────────────────────────────────────────────────────────
|
|
@@ -757,7 +751,7 @@ const SHARED_SCHEMA = [
|
|
|
757
751
|
description: 'Connect your Kick channel',
|
|
758
752
|
},
|
|
759
753
|
},
|
|
760
|
-
description: "Per-provider user-connection settings, keyed by provider name (`connections: { twitch: {…} }`)
|
|
754
|
+
description: "Per-provider user-connection settings, keyed by provider name (`connections: { twitch: {…} }`), public values only, never client secrets (those are the CONNECTIONS_<PROVIDER>_CLIENT_ID/_SECRET env pair). The set of providers is OPEN (a brand ships its own as `src/connections/<name>.js`), so the section stays free-form; the keys every entry may carry are `enabled` (the packaged providers default to false, so set it true to offer one; a brand's own provider is on unless this is false), `scope` (an array that wins over the provider module's default), `name` and `logo` (what the account page's card draws; the CONFIG is the only card list, and `logo` is the name of a mark @omega.js/web ships in core/logos/brandmarks/original, rendered inline, or a full URL rendered as an img), and `description` (the line under the card's title). The five packaged providers carry all three by default, so enabling one is one line. docs/backend/connections.md",
|
|
761
755
|
},
|
|
762
756
|
|
|
763
757
|
// ── repo (where the brand hosts its source; #883) ───────────────────────
|
|
@@ -769,7 +763,7 @@ const SHARED_SCHEMA = [
|
|
|
769
763
|
path: 'repo',
|
|
770
764
|
type: 'object',
|
|
771
765
|
required: false,
|
|
772
|
-
description: 'Where the brand hosts its source. Presence enables the repo service; the block is provider + org and nothing else, since every repo name derives from `<brand.id>-<role
|
|
766
|
+
description: 'Where the brand hosts its source. Presence enables the repo service; the block is provider + org and nothing else, since every repo name derives from `<brand.id>-<role>`.',
|
|
773
767
|
},
|
|
774
768
|
{
|
|
775
769
|
path: 'repo.provider',
|
|
@@ -796,19 +790,19 @@ const SHARED_SCHEMA = [
|
|
|
796
790
|
path: 'domain.providers',
|
|
797
791
|
type: 'object',
|
|
798
792
|
required: false,
|
|
799
|
-
description: "The brand's REGISTRAR, named as the one KEY under it ({ namecheap: {} })
|
|
793
|
+
description: "The brand's REGISTRAR, named as the one KEY under it ({ namecheap: {} }). Presence picks it, and no entry means nothing chosen, so the domain service skips. The provider set is open; the entry may be empty.",
|
|
800
794
|
},
|
|
801
795
|
{
|
|
802
796
|
path: 'domain.providers.namecheap',
|
|
803
797
|
type: 'object',
|
|
804
798
|
required: false,
|
|
805
|
-
description: 'Namecheap as the registrar
|
|
799
|
+
description: 'Namecheap as the registrar, the one provider whose nameservers the domain service points at the Cloudflare zone via API (NAMECHEAP_USERNAME + NAMECHEAP_API_KEY in .env). An empty object is the whole declaration; every other registrar gets manual instructions.',
|
|
806
800
|
},
|
|
807
801
|
{
|
|
808
802
|
path: 'domain.email.providers',
|
|
809
803
|
type: 'object',
|
|
810
804
|
required: false,
|
|
811
|
-
description: "The brand's MAILBOX provider, named as the one KEY under it ({ cloudflare: {} } | { squarespace: {} } | { privateemail: {} })
|
|
805
|
+
description: "The brand's MAILBOX provider, named as the one KEY under it ({ cloudflare: {} } | { squarespace: {} } | { privateemail: {} }). Presence picks it; no entry leaves the edge service's email-routing operations off.",
|
|
812
806
|
},
|
|
813
807
|
{
|
|
814
808
|
path: 'domain.email.forwarding',
|
|
@@ -823,11 +817,11 @@ const SHARED_SCHEMA = [
|
|
|
823
817
|
type: 'boolean',
|
|
824
818
|
required: false,
|
|
825
819
|
default: true,
|
|
826
|
-
description: 'false = the edge service skips entirely
|
|
820
|
+
description: 'false = the edge service skips entirely: no zone, DNS, settings, rules, speed-test or worker reconciliation for this brand.',
|
|
827
821
|
},
|
|
828
822
|
{
|
|
829
823
|
path: 'edge.providers.cloudflare',
|
|
830
|
-
type: 'object',
|
|
824
|
+
type: 'object', open: true,
|
|
831
825
|
required: false,
|
|
832
826
|
description: 'Cloudflare zone reconciliation (@omega.js/manager cloudflare service): dns, settings, rules, cacheRules, speedTest, workers. Tokens live in .env.',
|
|
833
827
|
},
|
|
@@ -841,7 +835,7 @@ const SHARED_SCHEMA = [
|
|
|
841
835
|
path: 'edge.providers.cloudflare.rules.redirect',
|
|
842
836
|
type: 'array',
|
|
843
837
|
required: false,
|
|
844
|
-
description: "The zone's dynamic redirect rules, ORDERED
|
|
838
|
+
description: "The zone's dynamic redirect rules, ORDERED, and the ONE home for a TEMPLATED redirect, i.e. one whose destination is computed from the request path: [{ name, expression, statusCode, preserveQueryString, targetUrl, enabled }]. `expression` and `targetUrl` ({ value } for a fixed URL, { expression } for a computed one) are Cloudflare's own filter language, because only the edge can answer a URL the build cannot enumerate: DashQR's printed `/c/<id>` codes redirect to `/code?id=<id>` with `targetUrl.expression: concat(\"https://\", http.host, \"/code?id=\", substring(http.request.uri.path, 3))`. The @omega.js/manager edge service reconciles them by `name`. A redirect whose URLs CAN be enumerated is a redirect PAGE instead (docs/web/index.md), never config.",
|
|
845
839
|
},
|
|
846
840
|
|
|
847
841
|
// ── captcha (role: bot defense; provider-discriminated) ──────────────────
|
|
@@ -849,13 +843,13 @@ const SHARED_SCHEMA = [
|
|
|
849
843
|
path: 'captcha.providers.recaptcha.project',
|
|
850
844
|
type: 'string',
|
|
851
845
|
required: false,
|
|
852
|
-
description: "The brand's OWN GCP project hosting the classic reCAPTCHA key
|
|
846
|
+
description: "The brand's OWN GCP project hosting the classic reCAPTCHA key, used only for the console deep-link in guidance. Site/secret keys stay in .env.",
|
|
853
847
|
},
|
|
854
848
|
{
|
|
855
849
|
path: 'captcha.providers.recaptcha.siteKey',
|
|
856
850
|
type: 'string',
|
|
857
851
|
required: false,
|
|
858
|
-
description: 'Classic reCAPTCHA site key rendered client-side. Public by design
|
|
852
|
+
description: 'Classic reCAPTCHA site key rendered client-side. Public by design; the secret half stays in .env (RECAPTCHA_SECRET_KEY).',
|
|
859
853
|
},
|
|
860
854
|
{
|
|
861
855
|
path: 'captcha.providers.recaptcha.domainsConfirmed',
|
|
@@ -876,7 +870,7 @@ const SHARED_SCHEMA = [
|
|
|
876
870
|
path: 'forms.providers.slapform.formId',
|
|
877
871
|
type: 'string',
|
|
878
872
|
required: false,
|
|
879
|
-
description: 'Slapform form id
|
|
873
|
+
description: 'Slapform form id; the contact page posts to https://api.slapform.com/{formId}. Interactive manager runs land it here.',
|
|
880
874
|
},
|
|
881
875
|
{
|
|
882
876
|
path: 'forms.providers.slapform.templateFormId',
|
|
@@ -896,7 +890,7 @@ const SHARED_SCHEMA = [
|
|
|
896
890
|
type: 'object',
|
|
897
891
|
required: false,
|
|
898
892
|
default: { id: 'grandmaster', name: 'Grandmaster' },
|
|
899
|
-
description: 'Tier granted to the form-owner account ({ id, name })
|
|
893
|
+
description: 'Tier granted to the form-owner account ({ id, name }), for Slapform operators only.',
|
|
900
894
|
},
|
|
901
895
|
|
|
902
896
|
// ── inbound (role: inbound conversations; per-channel providers) ─────────
|
|
@@ -917,7 +911,7 @@ const SHARED_SCHEMA = [
|
|
|
917
911
|
path: 'inbound.chat.providers.chatsy.accountId',
|
|
918
912
|
type: 'string',
|
|
919
913
|
required: false,
|
|
920
|
-
description: "Chatsy owner-account uid the agent belongs to
|
|
914
|
+
description: "Chatsy owner-account uid the agent belongs to, the account whose subscription the chat service reconciles to `plan`. The service resolves it from the agent itself; set it only when the agent's owner is provisioned elsewhere.",
|
|
921
915
|
},
|
|
922
916
|
{
|
|
923
917
|
path: 'inbound.chat.providers.chatsy.templateAgentId',
|
|
@@ -937,7 +931,7 @@ const SHARED_SCHEMA = [
|
|
|
937
931
|
type: 'object',
|
|
938
932
|
required: false,
|
|
939
933
|
default: { id: 'max', name: 'Max' },
|
|
940
|
-
description: 'Tier granted to the agent-owner account ({ id, name })
|
|
934
|
+
description: 'Tier granted to the agent-owner account ({ id, name }), for Chatsy operators only.',
|
|
941
935
|
},
|
|
942
936
|
{
|
|
943
937
|
path: 'inbound.chat.providers.chatsy.sponsorshipsUrl',
|
|
@@ -982,7 +976,7 @@ const SHARED_SCHEMA = [
|
|
|
982
976
|
type: 'object',
|
|
983
977
|
required: false,
|
|
984
978
|
default: { id: 'max', name: 'Max' },
|
|
985
|
-
description: 'Tier granted to the agent-owner account ({ id, name })
|
|
979
|
+
description: 'Tier granted to the agent-owner account ({ id, name }), for Replyify operators only.',
|
|
986
980
|
},
|
|
987
981
|
{
|
|
988
982
|
path: 'inbound.email.providers.replyify.discount',
|
|
@@ -997,7 +991,7 @@ const SHARED_SCHEMA = [
|
|
|
997
991
|
type: 'boolean',
|
|
998
992
|
required: false,
|
|
999
993
|
default: true,
|
|
1000
|
-
description: 'false = the search service skips entirely
|
|
994
|
+
description: 'false = the search service skips entirely: the property is never verified and no sitemap is submitted (submitSitemap only turns the sitemap half off).',
|
|
1001
995
|
},
|
|
1002
996
|
{
|
|
1003
997
|
path: 'search.providers.searchConsole.submitSitemap',
|
|
@@ -1025,13 +1019,13 @@ const SHARED_SCHEMA = [
|
|
|
1025
1019
|
path: 'certificates.enabled',
|
|
1026
1020
|
type: 'boolean',
|
|
1027
1021
|
required: false,
|
|
1028
|
-
description: 'false = the certificates service skips entirely
|
|
1022
|
+
description: 'false = the certificates service skips entirely: no bundle ids, no signing certificates, no provisioning profiles for this brand. Absent reads as ON for brands with a desktop/mobile target (the service still skips one with neither).',
|
|
1029
1023
|
},
|
|
1030
1024
|
{
|
|
1031
1025
|
path: 'certificates.providers.apple.bundleIdPrefix',
|
|
1032
1026
|
type: 'string',
|
|
1033
1027
|
required: false,
|
|
1034
|
-
description: "Reverse-DNS prefix the brand's bundle id is composed from ('com.mycompany' + brand.id → com.mycompany.my.brand). The brand's own answer
|
|
1028
|
+
description: "Reverse-DNS prefix the brand's bundle id is composed from ('com.mycompany' + brand.id → com.mycompany.my.brand). The brand's own answer: the onboard wizard seeds it and setup asks for it; unset, the Apple operations have no id to reconcile.",
|
|
1035
1029
|
},
|
|
1036
1030
|
{
|
|
1037
1031
|
path: 'certificates.providers.apple.capabilities',
|
|
@@ -1049,7 +1043,7 @@ const SHARED_SCHEMA = [
|
|
|
1049
1043
|
path: 'certificates.providers.apple.certificates',
|
|
1050
1044
|
type: 'array',
|
|
1051
1045
|
required: false,
|
|
1052
|
-
description: "Certificate types managed for the Apple Developer account ([{ type, manual }])
|
|
1046
|
+
description: "Certificate types managed for the Apple Developer account ([{ type, manual }]); `manual: true` marks the ones Apple's API cannot create, which the Account Holder downloads from the portal. Unset uses the framework set.",
|
|
1053
1047
|
},
|
|
1054
1048
|
|
|
1055
1049
|
// ── publishing (role: ship credentials; no provider) ─────────────────
|
|
@@ -1057,7 +1051,7 @@ const SHARED_SCHEMA = [
|
|
|
1057
1051
|
path: 'publishing.enabled',
|
|
1058
1052
|
type: 'boolean',
|
|
1059
1053
|
required: false,
|
|
1060
|
-
description: "The manage walk's ship-credential gate
|
|
1054
|
+
description: "The manage walk's ship-credential gate: the `publishing` service asks for every developer key and listing id the brand's declared formats need (`targets.<name>.platforms.<platform>.formats`). `false` is the permanent opt-out the gate's Disable lands; absence means ask, and no default is materialized. Dropping ONE store is the declaration's job (`platforms.<store>.formats.store: false`), never this switch.",
|
|
1061
1055
|
},
|
|
1062
1056
|
|
|
1063
1057
|
// ── devlog (role: commit-digest publishing; provider-discriminated) ──────
|
|
@@ -1071,7 +1065,7 @@ const SHARED_SCHEMA = [
|
|
|
1071
1065
|
path: 'devlog.enabled',
|
|
1072
1066
|
type: 'boolean',
|
|
1073
1067
|
required: false,
|
|
1074
|
-
description:
|
|
1068
|
+
description: "true PUBLISHES AI-written commit-digest posts to the brand's live website. Case 3 (docs/shared/config.md): the literal true is the only ON, absence is off, and no default is materialized, so publishing is never implicit.",
|
|
1075
1069
|
},
|
|
1076
1070
|
|
|
1077
1071
|
// ── seo ──────────────────────────────────────────────────────────────────
|
|
@@ -1079,7 +1073,7 @@ const SHARED_SCHEMA = [
|
|
|
1079
1073
|
path: 'seo',
|
|
1080
1074
|
type: 'object',
|
|
1081
1075
|
required: false,
|
|
1082
|
-
description:
|
|
1076
|
+
description: "Parasite-SEO content: seo.github.content is the @omega.js/manager seo service's repos, and big content blocks may live in the config/seo.json5 sidecar. The indexing switch is NOT here: it is `targets.web.meta.index`, the same name a page writes.",
|
|
1083
1077
|
},
|
|
1084
1078
|
|
|
1085
1079
|
// ── account ──────────────────────────────────────────────────────────────
|
|
@@ -1087,7 +1081,7 @@ const SHARED_SCHEMA = [
|
|
|
1087
1081
|
path: 'account',
|
|
1088
1082
|
type: 'object',
|
|
1089
1083
|
required: false,
|
|
1090
|
-
description: "Managed Firebase Auth accounts (@omega.js/manager account service): enabled + admins ([{ email, account, marketing }]; '{domain}' templates to the brand domain). Owner-defined
|
|
1084
|
+
description: "Managed Firebase Auth accounts (@omega.js/manager account service): enabled + admins ([{ email, account, marketing }]; '{domain}' templates to the brand domain). Owner-defined, typically set once in the COMPANY omega.json5 (arrays replace, so the company list wins whole). Passwords NEVER live here: per-account OMEGA_ACCOUNT_PASSWORD__* env vars, the config/hooks/account/password.js hook, or the ACCOUNT_PASSWORD_SEED derivation.",
|
|
1091
1085
|
},
|
|
1092
1086
|
|
|
1093
1087
|
// ── reviews ──────────────────────────────────────────────────────────────
|
|
@@ -1143,7 +1137,7 @@ const SHARED_SCHEMA = [
|
|
|
1143
1137
|
path: 'marketing.campaigns.providers.sendgrid.groups.account',
|
|
1144
1138
|
type: 'integer',
|
|
1145
1139
|
required: false,
|
|
1146
|
-
description:
|
|
1140
|
+
description: 'SendGrid unsubscribe (ASM) group id for account-action email (deletion, data requests), and the fallback for any send naming no group. Written back by the campaigns service, which provisions the group by name; ASM ids are per SendGrid ACCOUNT, so this is config and never code. Unset makes @omega.js/backend fail the send loudly.',
|
|
1147
1141
|
},
|
|
1148
1142
|
{
|
|
1149
1143
|
path: 'marketing.campaigns.providers.sendgrid.groups.marketing',
|
|
@@ -1186,14 +1180,14 @@ const SHARED_SCHEMA = [
|
|
|
1186
1180
|
path: 'marketing.newsletter.content',
|
|
1187
1181
|
type: 'object|array',
|
|
1188
1182
|
required: false,
|
|
1189
|
-
description:
|
|
1183
|
+
description: "Newsletter-PIPELINE config (sources, categories, tone, template, theme, sponsorships), a single object or an array whose first entry the generator uses. Role-level on purpose: it configures @omega.js/backend's generator, not Beehiiv.",
|
|
1190
1184
|
},
|
|
1191
1185
|
{
|
|
1192
1186
|
path: 'marketing.prune.enabled',
|
|
1193
1187
|
type: 'boolean',
|
|
1194
1188
|
required: false,
|
|
1195
1189
|
default: true,
|
|
1196
|
-
description: 'Monthly cold-contact prune across both providers. ON by default
|
|
1190
|
+
description: 'Monthly cold-contact prune across both providers. ON by default and materialized into every brand config; false is the per-brand off switch.',
|
|
1197
1191
|
},
|
|
1198
1192
|
|
|
1199
1193
|
// ── blog ─────────────────────────────────────────────────────────────────
|
|
@@ -1221,14 +1215,14 @@ const SHARED_SCHEMA = [
|
|
|
1221
1215
|
path: 'directory',
|
|
1222
1216
|
type: 'object',
|
|
1223
1217
|
required: false,
|
|
1224
|
-
description: "Directory participation (@omega.js/manager directory service): { enabled } opts in to pushing this brand's entry into the parent project's `brands` collection. Absent or false never pushes. Needs `company.id` to name a parent
|
|
1218
|
+
description: "Directory participation (@omega.js/manager directory service): { enabled } opts in to pushing this brand's entry into the parent project's `brands` collection. Absent or false never pushes. Needs `company.id` to name a parent and DIRECTORY_SERVICE_ACCOUNT in the brand .env.",
|
|
1225
1219
|
},
|
|
1226
1220
|
{
|
|
1227
1221
|
path: 'directory.enabled',
|
|
1228
1222
|
type: 'boolean',
|
|
1229
1223
|
required: false,
|
|
1230
1224
|
default: false,
|
|
1231
|
-
description: 'true opts the brand into the directory push. Default false
|
|
1225
|
+
description: 'true opts the brand into the directory push. Default false, so participation is never implicit.',
|
|
1232
1226
|
},
|
|
1233
1227
|
|
|
1234
1228
|
// ── sponsorships ─────────────────────────────────────────────────────────
|
|
@@ -1236,7 +1230,7 @@ const SHARED_SCHEMA = [
|
|
|
1236
1230
|
path: 'sponsorships',
|
|
1237
1231
|
type: 'object',
|
|
1238
1232
|
required: false,
|
|
1239
|
-
description: "The brand's sponsorship terms
|
|
1233
|
+
description: "The brand's sponsorship terms, the first directory BLOCK and the section the server service also publishes. Public terms only: { acceptable, unacceptable, prices }.",
|
|
1240
1234
|
},
|
|
1241
1235
|
{
|
|
1242
1236
|
path: 'sponsorships.acceptable',
|
|
@@ -1254,7 +1248,7 @@ const SHARED_SCHEMA = [
|
|
|
1254
1248
|
path: 'sponsorships.prices',
|
|
1255
1249
|
type: 'object',
|
|
1256
1250
|
required: false,
|
|
1257
|
-
description: "Price in USD per placement type
|
|
1251
|
+
description: "Price in USD per placement type, placement key to number ({ 'guest-post': 70, 'link-insertion': 50 }). A placement with no price is not for sale.",
|
|
1258
1252
|
},
|
|
1259
1253
|
|
|
1260
1254
|
// ── ports (dev-only) ─────────────────────────────────────────────────────
|
|
@@ -1262,7 +1256,7 @@ const SHARED_SCHEMA = [
|
|
|
1262
1256
|
path: 'ports',
|
|
1263
1257
|
type: 'object',
|
|
1264
1258
|
required: false,
|
|
1265
|
-
description: 'Explicit dev-port pins
|
|
1259
|
+
description: 'Explicit dev-port pins. Unset ports auto-allocate (classic defaults, bump-if-taken); a pinned port never bumps, and a busy pin is a hard error. Keys: auth, functions, firestore, database, hosting, storage, pubsub, ui, website, livereload, cdp. Dev/emulator only; production never reads this.',
|
|
1266
1260
|
},
|
|
1267
1261
|
|
|
1268
1262
|
// ── theme ────────────────────────────────────────────────────────────────
|
|
@@ -1270,7 +1264,7 @@ const SHARED_SCHEMA = [
|
|
|
1270
1264
|
path: 'theme.id',
|
|
1271
1265
|
type: 'string',
|
|
1272
1266
|
required: false,
|
|
1273
|
-
description: "Theme id (seeded 'classy' at onboarding). Project-owned
|
|
1267
|
+
description: "Theme id (seeded 'classy' at onboarding). Project-owned: the manager never overwrites it.",
|
|
1274
1268
|
},
|
|
1275
1269
|
{
|
|
1276
1270
|
path: 'theme.appearance',
|
|
@@ -1285,7 +1279,7 @@ const SHARED_SCHEMA = [
|
|
|
1285
1279
|
path: 'ai.enabled',
|
|
1286
1280
|
type: 'boolean',
|
|
1287
1281
|
required: false,
|
|
1288
|
-
description: "The manager's AI-provider setup gate
|
|
1282
|
+
description: "The manager's AI-provider setup gate: the `ai` service asks once for OPENAI_API_KEY / ANTHROPIC_API_KEY. `false` is the permanent opt-out the gate's Disable lands; absence means ask. No default is materialized, so a brand that never answers is never re-shaped.",
|
|
1289
1283
|
},
|
|
1290
1284
|
|
|
1291
1285
|
// ── translation ──────────────────────────────────────────────────────────
|
|
@@ -1313,7 +1307,7 @@ const SHARED_SCHEMA = [
|
|
|
1313
1307
|
path: 'translation.providers',
|
|
1314
1308
|
type: 'object',
|
|
1315
1309
|
required: false,
|
|
1316
|
-
description: "AI translation provider, keyed by name
|
|
1310
|
+
description: "AI translation provider, keyed by name; presence picks the engine ({ claude: {} } or { chatgpt: {} }). 'claude' (the default when the block is absent) rides the local Claude Code install with no API key; 'chatgpt' uses the OpenAI API via OPENAI_API_KEY in env.",
|
|
1317
1311
|
},
|
|
1318
1312
|
{
|
|
1319
1313
|
path: 'translation.model',
|
|
@@ -1333,65 +1327,15 @@ const SHARED_SCHEMA = [
|
|
|
1333
1327
|
description: "Web only: the page routes to translate, as globs with `!` negation, read in order like a .gitignore: the LAST pattern that matches a route decides it, and a route no pattern matches is not translated. A folder pattern covers the folder itself (`!blog/**` excludes `/blog` and everything under it). The default ['**', '!blog/**'] translates the whole site except the blog, which is where the words (and the cost) pile up. A brand list REPLACES the default outright. A page overrides it for itself with `translation.include: true`/`false` in its own frontmatter, the same key name one level down (docs/web/frontmatter.md). The framework's own default pages carry their own exclusion and are never in this list's hands.",
|
|
1334
1328
|
},
|
|
1335
1329
|
|
|
1336
|
-
// ── client (the @omega.js/client runtime blob)
|
|
1337
|
-
|
|
1338
|
-
// so it is deliberately NOT enumerated key by key here. `consent` is the
|
|
1339
|
-
// exception (#383): it decides whether a visitor is tracked at all, which is
|
|
1340
|
-
// a legal surface, not a preference — a typo that silently disabled the
|
|
1341
|
-
// banner would ship a site with no consent gate and no error.
|
|
1342
|
-
//
|
|
1343
|
-
// The three below are the second exception (#650 — found adopting omega in a
|
|
1344
|
-
// consumer): keys a BRAND authors. They work (they reach the client payload
|
|
1345
|
-
// and change what the site does), so every validate run told the brand that
|
|
1346
|
-
// turned one off it might be a typo. The rest of the blob stays the client's.
|
|
1347
|
-
{
|
|
1348
|
-
path: 'client.consent.enabled',
|
|
1349
|
-
type: 'boolean',
|
|
1350
|
-
required: false,
|
|
1351
|
-
default: true,
|
|
1352
|
-
description: 'The consent banner + the provider-script gate (default true). false ships NO banner — legal only for a site that loads no analytics/marketing provider at all.',
|
|
1353
|
-
},
|
|
1354
|
-
{
|
|
1355
|
-
path: 'client.consent.config.position',
|
|
1356
|
-
type: 'string',
|
|
1357
|
-
required: false,
|
|
1358
|
-
enum: ['bottom-left', 'bottom-right', 'bottom'],
|
|
1359
|
-
description: "Where the panel sits. 'bottom' is the centered full-width form.",
|
|
1360
|
-
},
|
|
1361
|
-
{
|
|
1362
|
-
path: 'client.consent.config.content',
|
|
1363
|
-
type: 'object',
|
|
1364
|
-
required: false,
|
|
1365
|
-
description: "Banner copy: message, panelIntro, accept, customize, acceptAll, acceptNone (a literal `{terms}`/`{cookies}` links the terms/cookie-policy page). Category labels are framework copy — a brand renames the buttons, not the categories.",
|
|
1366
|
-
},
|
|
1367
|
-
{
|
|
1368
|
-
path: 'client.auth.config.policy',
|
|
1369
|
-
type: 'string',
|
|
1370
|
-
required: false,
|
|
1371
|
-
enum: ['authenticated', 'unauthenticated', 'disabled'],
|
|
1372
|
-
description: "Who a page is FOR: 'authenticated' redirects a signed-out visitor to the signin route, 'unauthenticated' redirects a signed-in one away, 'disabled' skips the auth module entirely (a vert iframe). Absent = no policy, which is the site-wide answer — the auth/admin layouts set theirs in page frontmatter, so a brand only sets this to blanket a whole site.",
|
|
1373
|
-
},
|
|
1374
|
-
{
|
|
1375
|
-
path: 'client.exitPopup.enabled',
|
|
1376
|
-
type: 'boolean',
|
|
1377
|
-
required: false,
|
|
1378
|
-
default: true,
|
|
1379
|
-
description: 'The exit-intent offer popup (default true). false ships no popup at all; its copy, timeout and avatars live under client.exitPopup.config.',
|
|
1380
|
-
},
|
|
1381
|
-
{
|
|
1382
|
-
path: 'client.serviceWorker.enabled',
|
|
1383
|
-
type: 'boolean',
|
|
1384
|
-
required: false,
|
|
1385
|
-
default: true,
|
|
1386
|
-
description: 'Registers the site service worker (default true) — the offline/refresh lane and the push-notification registration ride it. false unregisters any worker the visitor already has.',
|
|
1387
|
-
},
|
|
1330
|
+
// ── client (the @omega.js/client runtime blob): its own file ────────────
|
|
1331
|
+
...CLIENT_RULES,
|
|
1388
1332
|
|
|
1389
1333
|
// ── targets ──────────────────────────────────────────────────────────────
|
|
1390
1334
|
{
|
|
1391
1335
|
path: 'targets',
|
|
1392
1336
|
type: 'object',
|
|
1393
1337
|
required: false,
|
|
1394
|
-
description:
|
|
1338
|
+
description: 'Every key is a target NAME, which is the folder `targets/<name>`, the `--target=<name>` word and the derived-repo suffix. Key presence = target enabled; the value is an object of target-scoped config (any shared key inside overrides it) and MUST declare `type`: web/backend/desktop/extension/mobile, or `custom` for a target the manager drives entirely through its own package.json scripts. Anything else is an error.',
|
|
1395
1339
|
},
|
|
1396
1340
|
];
|
|
1397
1341
|
|
|
@@ -1405,7 +1349,7 @@ const TARGET_SCHEMAS = {
|
|
|
1405
1349
|
path: 'hosting',
|
|
1406
1350
|
type: 'object',
|
|
1407
1351
|
required: false,
|
|
1408
|
-
description: 'Where this web target is SERVED from
|
|
1352
|
+
description: 'Where this web target is SERVED from. Web targets only: a non-web target carrying it is a validation error.',
|
|
1409
1353
|
},
|
|
1410
1354
|
{
|
|
1411
1355
|
path: 'hosting.provider',
|
|
@@ -1428,7 +1372,7 @@ const TARGET_SCHEMAS = {
|
|
|
1428
1372
|
type: 'boolean',
|
|
1429
1373
|
required: false,
|
|
1430
1374
|
default: true,
|
|
1431
|
-
description: "false takes the WHOLE site out of search: every page emits noindex and sitemap.xml, llms.txt and pages.json list nothing. It is the site-wide DEFAULT of the one flag every signal reads
|
|
1375
|
+
description: "false takes the WHOLE site out of search: every page emits noindex and sitemap.xml, llms.txt and pages.json list nothing. It is the site-wide DEFAULT of the one flag every signal reads, so a page's own `meta.index: true` still exempts it. Case 2 (docs/shared/config.md): default ON, and the literal false is the only OFF.",
|
|
1432
1376
|
},
|
|
1433
1377
|
{
|
|
1434
1378
|
path: 'imagemin',
|
|
@@ -1440,13 +1384,13 @@ const TARGET_SCHEMAS = {
|
|
|
1440
1384
|
path: 'dev.limitCollections',
|
|
1441
1385
|
type: 'object',
|
|
1442
1386
|
required: false,
|
|
1443
|
-
description: "Dev-only collection sampling
|
|
1387
|
+
description: "Dev-only collection sampling: collection name → max documents ({ posts: 50 }), plus `randomize: true` for a random sample instead of the first N. Collection names are @omega.js/web's (posts, alternatives, team, updates) plus the brand's own `collections`, and the engine hard-fails an unknown one. Development builds only; production never samples.",
|
|
1444
1388
|
},
|
|
1445
1389
|
{
|
|
1446
1390
|
path: 'collections',
|
|
1447
1391
|
type: 'object',
|
|
1448
1392
|
required: false,
|
|
1449
|
-
description: "The brand's own content collections
|
|
1393
|
+
description: "The brand's own content collections: collection name → { field, size, title, description, permalink }. Documents live in `_<name>/`, and @omega.js/web generates the paginated listing page plus one page per category of `field` (the dotted frontmatter path the categories group on, e.g. 'doc.category'). A built-in collection name (posts, alternatives, team, updates) is an error.",
|
|
1450
1394
|
},
|
|
1451
1395
|
{
|
|
1452
1396
|
path: 'purgecss',
|
|
@@ -1458,7 +1402,7 @@ const TARGET_SCHEMAS = {
|
|
|
1458
1402
|
path: 'purgecss.safelist',
|
|
1459
1403
|
type: 'object|array',
|
|
1460
1404
|
required: false,
|
|
1461
|
-
description: "Selectors the content scan cannot see, merged OVER the framework's own safelist
|
|
1405
|
+
description: "Selectors the content scan cannot see, merged OVER the framework's own safelist. The object form takes PurgeCSS's lanes (standard, deep, greedy, keyframes); a bare array is PurgeCSS's shorthand for `standard`.",
|
|
1462
1406
|
},
|
|
1463
1407
|
{
|
|
1464
1408
|
path: 'purgecss.safelist.standard',
|
|
@@ -1476,7 +1420,7 @@ const TARGET_SCHEMAS = {
|
|
|
1476
1420
|
path: 'purgecss.safelist.greedy',
|
|
1477
1421
|
type: 'array',
|
|
1478
1422
|
required: false,
|
|
1479
|
-
description: 'Patterns (strings, compiled to RegExp) keeping every selector that contains a match
|
|
1423
|
+
description: 'Patterns (strings, compiled to RegExp) keeping every selector that contains a match, the lane for a runtime-stamped namespace.',
|
|
1480
1424
|
},
|
|
1481
1425
|
{
|
|
1482
1426
|
path: 'purgecss.safelist.keyframes',
|
|
@@ -1486,8 +1430,9 @@ const TARGET_SCHEMAS = {
|
|
|
1486
1430
|
},
|
|
1487
1431
|
],
|
|
1488
1432
|
|
|
1489
|
-
// Seeded from the sandbox brand's real @omega.js/backend config
|
|
1433
|
+
// Seeded from the sandbox brand's real @omega.js/backend config.
|
|
1490
1434
|
backend: [
|
|
1435
|
+
...OVERRIDE_RULES.backend,
|
|
1491
1436
|
// reviews, marketing, blog, dataRequest moved to SHARED_SCHEMA (#277); a
|
|
1492
1437
|
// targets.backend block still overrides them through the merge chain.
|
|
1493
1438
|
{
|
|
@@ -1495,7 +1440,7 @@ const TARGET_SCHEMAS = {
|
|
|
1495
1440
|
type: 'string',
|
|
1496
1441
|
required: false,
|
|
1497
1442
|
enum: BACKEND_PROJECT_TYPES,
|
|
1498
|
-
description: "How this backend RUNS and deploys
|
|
1443
|
+
description: "How this backend RUNS and deploys. 'firebase' (default) exports Cloud Functions; 'custom' runs the same app as an Express server on `PORT` for a container host (Render & co), with no Functions deploy, no emulator lane, and the target's own `deploy` script as the publish lane. Everything else (the auth middleware, the routes, the schemas, every helper) is identical in both modes.",
|
|
1499
1444
|
},
|
|
1500
1445
|
{
|
|
1501
1446
|
path: 'auth.signup.maxPerIpPerDay',
|
|
@@ -1506,9 +1451,9 @@ const TARGET_SCHEMAS = {
|
|
|
1506
1451
|
},
|
|
1507
1452
|
],
|
|
1508
1453
|
|
|
1509
|
-
//
|
|
1510
|
-
// is renamed `platforms` here (avoids targets.desktop.targets).
|
|
1454
|
+
// The per-OS key is `platforms` (avoids targets.desktop.targets).
|
|
1511
1455
|
desktop: [
|
|
1456
|
+
...OVERRIDE_RULES.desktop,
|
|
1512
1457
|
{
|
|
1513
1458
|
path: 'app.category',
|
|
1514
1459
|
type: 'string',
|
|
@@ -1524,7 +1469,7 @@ const TARGET_SCHEMAS = {
|
|
|
1524
1469
|
path: 'app.appId',
|
|
1525
1470
|
type: 'string',
|
|
1526
1471
|
required: false,
|
|
1527
|
-
description:
|
|
1472
|
+
description: 'The bundle identifier the app is signed and registered under. Unset, it derives as `certificates.providers.apple.bundleIdPrefix` plus `brand.id` with the dashes as dots, the very id the certificates service registers; a brand with no prefix falls back to the reverse-domain of `brand.url`, then `app.<brand.id>`. Set it only to stay on an id already-shipped builds carry.',
|
|
1528
1473
|
},
|
|
1529
1474
|
{
|
|
1530
1475
|
path: 'app.productName',
|
|
@@ -1567,7 +1512,7 @@ const TARGET_SCHEMAS = {
|
|
|
1567
1512
|
path: 'platforms',
|
|
1568
1513
|
type: 'object',
|
|
1569
1514
|
required: false,
|
|
1570
|
-
description: "What this desktop target SHIPS, plus each platform's install knobs
|
|
1515
|
+
description: "What this desktop target SHIPS, plus each platform's install knobs: `platforms.<mac|windows|linux>.formats.<dmg|nsis|deb|appimage|snap>`. Presence = enabled; drop a default with `false`. The install knobs beside `formats` (arch, the NSIS flags, mac entitlements) map onto the same electron-builder concepts, which @omega.js/desktop owns the target list of.",
|
|
1571
1516
|
},
|
|
1572
1517
|
{
|
|
1573
1518
|
path: 'platforms.mac',
|
|
@@ -1703,7 +1648,7 @@ const TARGET_SCHEMAS = {
|
|
|
1703
1648
|
path: 'autoUpdate.autoDownload',
|
|
1704
1649
|
type: 'boolean',
|
|
1705
1650
|
required: false,
|
|
1706
|
-
description: 'Whether a found update downloads on its own. Unset reads as true; false leaves the download to `
|
|
1651
|
+
description: 'Whether a found update downloads on its own. Unset reads as true; false leaves the download to `omega.autoUpdater` being asked for it.',
|
|
1707
1652
|
},
|
|
1708
1653
|
{
|
|
1709
1654
|
path: 'autoUpdate.startupDelayMs',
|
|
@@ -1749,7 +1694,7 @@ const TARGET_SCHEMAS = {
|
|
|
1749
1694
|
path: 'releases',
|
|
1750
1695
|
type: 'object',
|
|
1751
1696
|
required: false,
|
|
1752
|
-
description: "Presence opts the brand into the release surface (the site's download links, desktop publishing). WHICH repo is not configurable: it is the brand's one public `<brand.id>-releases
|
|
1697
|
+
description: "Presence opts the brand into the release surface (the site's download links, desktop publishing). WHICH repo is not configurable: it is the brand's one public `<brand.id>-releases`.",
|
|
1753
1698
|
},
|
|
1754
1699
|
{
|
|
1755
1700
|
path: 'restartManager.enabled',
|
|
@@ -1789,14 +1734,14 @@ const TARGET_SCHEMAS = {
|
|
|
1789
1734
|
path: 'remoteScripts.enabled',
|
|
1790
1735
|
type: 'boolean',
|
|
1791
1736
|
required: false,
|
|
1792
|
-
description: 'Emergency remote code execution in the main process
|
|
1737
|
+
description: 'Emergency remote code execution in the main process, OPT-IN: only `true` arms the lane, anything else leaves it inert.',
|
|
1793
1738
|
},
|
|
1794
1739
|
{
|
|
1795
1740
|
path: 'remoteScripts.url',
|
|
1796
1741
|
type: 'string',
|
|
1797
1742
|
required: false,
|
|
1798
1743
|
match: /^https?:\/\//,
|
|
1799
|
-
description: 'Remote-script source override (default `${brand.url}/data/scripts/main.js`). https-only at runtime
|
|
1744
|
+
description: 'Remote-script source override (default `${brand.url}/data/scripts/main.js`). https-only at runtime: a cleartext URL is refused (localhost excepted for dev).',
|
|
1800
1745
|
},
|
|
1801
1746
|
{
|
|
1802
1747
|
path: 'restartManager.feed.url',
|
|
@@ -1818,7 +1763,7 @@ const TARGET_SCHEMAS = {
|
|
|
1818
1763
|
path: 'platforms',
|
|
1819
1764
|
type: 'object',
|
|
1820
1765
|
required: false,
|
|
1821
|
-
description:
|
|
1766
|
+
description: "What this extension target SHIPS: `platforms.<chrome|firefox|edge>.formats.<zip|store>`. Presence = enabled; drop a default with `false`. The zip is attached to the release, the store is published to, and @omega.js/config's platforms.js says which credentials each store cannot ship without.",
|
|
1822
1767
|
},
|
|
1823
1768
|
{
|
|
1824
1769
|
path: 'platforms.chrome',
|
|
@@ -1842,7 +1787,7 @@ const TARGET_SCHEMAS = {
|
|
|
1842
1787
|
path: 'platforms.chrome.formats.store',
|
|
1843
1788
|
type: 'object|boolean',
|
|
1844
1789
|
required: false,
|
|
1845
|
-
description: 'The Chrome Web Store publish. Needs the CHROME_* API credentials plus `listings.chrome.id` (the walk asks for both
|
|
1790
|
+
description: 'The Chrome Web Store publish. Needs the CHROME_* API credentials plus `listings.chrome.id` (the walk asks for both).',
|
|
1846
1791
|
},
|
|
1847
1792
|
{
|
|
1848
1793
|
path: 'platforms.firefox',
|
|
@@ -1897,7 +1842,7 @@ const TARGET_SCHEMAS = {
|
|
|
1897
1842
|
path: 'platforms.edge.formats.store',
|
|
1898
1843
|
type: 'object|boolean',
|
|
1899
1844
|
required: false,
|
|
1900
|
-
description: 'The Edge Add-ons publish. Needs EDGE_CLIENT_ID + EDGE_API_KEY plus `listings.edge.id` (the Partner Center product id
|
|
1845
|
+
description: 'The Edge Add-ons publish. Needs EDGE_CLIENT_ID + EDGE_API_KEY plus `listings.edge.id` (the Partner Center product id).',
|
|
1901
1846
|
},
|
|
1902
1847
|
{
|
|
1903
1848
|
path: 'categories',
|
|
@@ -1905,20 +1850,20 @@ const TARGET_SCHEMAS = {
|
|
|
1905
1850
|
required: false,
|
|
1906
1851
|
itemEnum: AMO_CATEGORIES,
|
|
1907
1852
|
default: ['alerts-updates'],
|
|
1908
|
-
description: "The AMO categories a FIRST Firefox publish lists the add-on under
|
|
1853
|
+
description: "The AMO categories a FIRST Firefox publish lists the add-on under: addons.mozilla.org requires them on a new listing, and the Firefox lane writes them into the `--amo-metadata` file it hands `web-ext sign`. Slugs come from AMO's own set; the default is `alerts-updates`, the most generic one that is not `other`. Chrome and Edge pick their category in their own dashboards.",
|
|
1909
1854
|
},
|
|
1910
1855
|
{
|
|
1911
1856
|
path: 'listings.chrome.id',
|
|
1912
1857
|
type: 'string',
|
|
1913
1858
|
required: false,
|
|
1914
|
-
description:
|
|
1859
|
+
description: 'The Chrome Web Store ITEM ID the publish uploads to, the 32-letter id in the listing URL. Public by design, so it lives here and not in .env; the manage walk asks for it.',
|
|
1915
1860
|
},
|
|
1916
1861
|
{
|
|
1917
1862
|
path: 'listings.chrome.url',
|
|
1918
1863
|
type: 'string',
|
|
1919
1864
|
required: false,
|
|
1920
1865
|
match: /^https?:\/\//,
|
|
1921
|
-
description: "Chrome Web Store listing URL. Feeds site.targets.extension.listings.chrome
|
|
1866
|
+
description: "Chrome Web Store listing URL. Feeds site.targets.extension.listings.chrome, the /extension page's button and its /extension/chrome shortlink.",
|
|
1922
1867
|
},
|
|
1923
1868
|
{
|
|
1924
1869
|
path: 'listings.chrome.state',
|
|
@@ -1930,7 +1875,7 @@ const TARGET_SCHEMAS = {
|
|
|
1930
1875
|
path: 'listings.firefox.id',
|
|
1931
1876
|
type: 'string',
|
|
1932
1877
|
required: false,
|
|
1933
|
-
description: "The addons.mozilla.org ADD-ON ID, which IS the manifest's browser_specific_settings.gecko.id (AMO uses it as the add-on guid
|
|
1878
|
+
description: "The addons.mozilla.org ADD-ON ID, which IS the manifest's browser_specific_settings.gecko.id (AMO uses it as the add-on guid). Declared here it is authoritative: the firefox package writes it into the manifest. A brand that declares none gets the derived id pinned here by the extension's local scaffold, never by a publish.",
|
|
1934
1879
|
},
|
|
1935
1880
|
{
|
|
1936
1881
|
path: 'listings.firefox.url',
|
|
@@ -1949,7 +1894,7 @@ const TARGET_SCHEMAS = {
|
|
|
1949
1894
|
path: 'listings.edge.id',
|
|
1950
1895
|
type: 'string',
|
|
1951
1896
|
required: false,
|
|
1952
|
-
description:
|
|
1897
|
+
description: 'The Microsoft Edge Partner Center PRODUCT ID (a GUID) the publish uploads to. Public by design, so it lives here and not in .env; the manage walk asks for it.',
|
|
1953
1898
|
},
|
|
1954
1899
|
{
|
|
1955
1900
|
path: 'listings.edge.url',
|
|
@@ -2010,10 +1955,9 @@ const TARGET_SCHEMAS = {
|
|
|
2010
1955
|
};
|
|
2011
1956
|
|
|
2012
1957
|
// Declared top-level keys that are NOT config sections: `targets` is scoping
|
|
2013
|
-
// machinery,
|
|
2014
|
-
//
|
|
2015
|
-
|
|
2016
|
-
const NON_SECTION_KEYS = ['targets', 'url', 'type'];
|
|
1958
|
+
// machinery, `url` the target's RESOLVED public url (the `site.url` build fact),
|
|
1959
|
+
// `type` an entry's framework, and `enabled` the brand's on/off switch.
|
|
1960
|
+
const NON_SECTION_KEYS = ['targets', 'url', 'type', 'enabled'];
|
|
2017
1961
|
|
|
2018
1962
|
/** The top-level sections a rule array declares (machinery keys excluded). */
|
|
2019
1963
|
const sectionsOf = (rules) => [...new Set(rules.map((rule) => rule.path.split('.')[0]))].filter((section) => !NON_SECTION_KEYS.includes(section));
|