@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
|
@@ -70,6 +70,49 @@ module.exports = defineCases({
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: 'baseConfig: files never pack the target\'s scratch and state dirs (#866)',
|
|
75
|
+
run: (ctx) => {
|
|
76
|
+
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
77
|
+
const files = baseConfig({}).files;
|
|
78
|
+
// The boot runner stages .omega/test-app with symlinks into the target and the
|
|
79
|
+
// packager followed them (dangling after a folder rename); none of these dirs
|
|
80
|
+
// is app content anyway.
|
|
81
|
+
for (const dir of ['.omega', '.claude', '.temp', '.cache', '.gh-runners', 'test']) {
|
|
82
|
+
ctx.expect(files).toContain(`!${dir}/**`);
|
|
83
|
+
}
|
|
84
|
+
// src/ stays: the runtime reads src/integrations/* from the app root.
|
|
85
|
+
ctx.expect(files.includes('!src/**')).toBe(false);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'baseConfig: the DMG is signed with the Developer ID identity (#891)',
|
|
90
|
+
run: (ctx) => {
|
|
91
|
+
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
92
|
+
const out = baseConfig({ app: { productName: 'Deployment Playground' } });
|
|
93
|
+
|
|
94
|
+
// Gatekeeper assesses a downloaded image by its OWN signature
|
|
95
|
+
// (`--context context:primary-signature`), and electron-builder leaves
|
|
96
|
+
// the image unsigned unless told: run 34735658588 notarized and stapled
|
|
97
|
+
// the DMG, then spctl refused it for the missing signature.
|
|
98
|
+
ctx.expect(out.dmg.sign).toBe(true);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'notarizeHooks: the DMG is proved per artifact, BEFORE its upload (#891)',
|
|
103
|
+
run: (ctx) => {
|
|
104
|
+
const { notarizeHooks } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
105
|
+
const hooks = notarizeHooks();
|
|
106
|
+
|
|
107
|
+
// electron-builder awaits `artifactBuildCompleted` before it emits the
|
|
108
|
+
// `artifactCreated` the publisher uploads on; `afterAllArtifactBuild`
|
|
109
|
+
// runs after every upload is queued. Run 34738410986 published a signed
|
|
110
|
+
// and notarized DMG with no staple because the proof ran there.
|
|
111
|
+
ctx.expect(hooks.afterSign).toContain(path.join('hooks', 'notarize.js'));
|
|
112
|
+
ctx.expect(hooks.artifactBuildCompleted).toContain(path.join('hooks', 'notarize-artifacts.js'));
|
|
113
|
+
ctx.expect(hooks.afterAllArtifactBuild).toBeUndefined();
|
|
114
|
+
},
|
|
115
|
+
},
|
|
73
116
|
{
|
|
74
117
|
name: 'baseConfig: artifact names carry NO version, from @omega.js/config\'s ONE rule (#620)',
|
|
75
118
|
run: (ctx) => {
|
|
@@ -82,19 +125,22 @@ module.exports = defineCases({
|
|
|
82
125
|
// github.com/<org>/<repo>/releases/latest/download/<asset> a stable
|
|
83
126
|
// direct-download URL — the site derives its buttons from THESE names,
|
|
84
127
|
// so a second spelling here is a dead download button.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
ctx.expect(out.
|
|
128
|
+
// The segment is the FORMAT (#867), the same word the site's
|
|
129
|
+
// /download/<platform>/<format> link carries.
|
|
130
|
+
ctx.expect(out.dmg.artifactName).toBe(names.mac.dmg);
|
|
131
|
+
ctx.expect(out.nsis.artifactName).toBe(names.windows.nsis);
|
|
132
|
+
ctx.expect(out.deb.artifactName).toBe(names.linux.deb);
|
|
88
133
|
ctx.expect(out.appImage.artifactName).toBe(names.linux.appimage);
|
|
134
|
+
ctx.expect(out.dmg.artifactName).toBe('Deployment-Playground-mac-dmg.dmg');
|
|
135
|
+
ctx.expect(out.nsis.artifactName).toBe('Deployment-Playground-windows-nsis.exe');
|
|
89
136
|
|
|
90
|
-
// The mac
|
|
91
|
-
//
|
|
92
|
-
ctx.expect(out.mac.artifactName.
|
|
93
|
-
ctx.expect(out.
|
|
94
|
-
ctx.expect(out.dmg.artifactName).toBe(undefined);
|
|
137
|
+
// The mac FALLBACK is the auto-update zip's, the one mac artifact that
|
|
138
|
+
// is not a declared format: nobody links it, the feed names it.
|
|
139
|
+
ctx.expect(out.mac.artifactName).toBe('Deployment-Playground-mac.${ext}');
|
|
140
|
+
ctx.expect(out.mac.artifactName.replace('${ext}', 'zip')).toBe('Deployment-Playground-mac.zip');
|
|
95
141
|
|
|
96
142
|
// Nothing keeps a ${version} token — every name is stable across releases.
|
|
97
|
-
for (const template of [out.mac.artifactName, out.nsis.artifactName, out.deb.artifactName, out.appImage.artifactName, out.linux.artifactName]) {
|
|
143
|
+
for (const template of [out.mac.artifactName, out.dmg.artifactName, out.nsis.artifactName, out.deb.artifactName, out.appImage.artifactName, out.linux.artifactName]) {
|
|
98
144
|
ctx.expect(template.includes('${version}')).toBe(false);
|
|
99
145
|
}
|
|
100
146
|
},
|
|
@@ -159,7 +205,7 @@ module.exports = defineCases({
|
|
|
159
205
|
|
|
160
206
|
// NSIS merges every arch into ONE installer, so windows is genuinely
|
|
161
207
|
// safe — its multi-arch default is never refused.
|
|
162
|
-
ctx.expect(baseConfig({ platforms: {
|
|
208
|
+
ctx.expect(baseConfig({ platforms: { windows: { arch: ['x64', 'ia32', 'arm64'] } } }, build).win.target[0].arch)
|
|
163
209
|
.toEqual(['x64', 'ia32', 'arm64']);
|
|
164
210
|
|
|
165
211
|
// One linux arch names one deb: an arm64-only brand ships fine.
|
|
@@ -280,28 +326,28 @@ module.exports = defineCases({
|
|
|
280
326
|
},
|
|
281
327
|
},
|
|
282
328
|
{
|
|
283
|
-
name: 'baseConfig: platforms.
|
|
329
|
+
name: 'baseConfig: platforms.windows.oneClick: false produces wizard installer',
|
|
284
330
|
run: (ctx) => {
|
|
285
331
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
286
|
-
const out = baseConfig({ platforms: {
|
|
332
|
+
const out = baseConfig({ platforms: { windows: { oneClick: false } } });
|
|
287
333
|
ctx.expect(out.nsis.oneClick).toBe(false);
|
|
288
334
|
ctx.expect(out.nsis.allowToChangeInstallationDirectory).toBe(true);
|
|
289
335
|
},
|
|
290
336
|
},
|
|
291
337
|
{
|
|
292
|
-
name: 'baseConfig:
|
|
338
|
+
name: 'baseConfig: a config that declares no platforms ships every format, snap included (#867)',
|
|
293
339
|
run: (ctx) => {
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
//
|
|
340
|
+
// Presence is the switch and every format defaults ON, so a caller that
|
|
341
|
+
// declares nothing gets the framework's whole shipping set. The snap's
|
|
342
|
+
// second gate is its credentials, which is what keeps a brand that has
|
|
343
|
+
// not run the Snap ask yet from failing CI.
|
|
298
344
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
299
345
|
const saved = process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
300
|
-
process.env.SNAPCRAFT_STORE_CREDENTIALS = 'fake-creds-blob';
|
|
346
|
+
process.env.SNAPCRAFT_STORE_CREDENTIALS = 'fake-creds-blob';
|
|
301
347
|
try {
|
|
302
348
|
const out = baseConfig({});
|
|
303
|
-
ctx.expect(out.linux.target.
|
|
304
|
-
ctx.expect(out.snap).
|
|
349
|
+
ctx.expect(out.linux.target.map((t) => t.target)).toEqual(['deb', 'AppImage', 'snap']);
|
|
350
|
+
ctx.expect(out.snap).toBeDefined();
|
|
305
351
|
} finally {
|
|
306
352
|
if (saved === undefined) delete process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
307
353
|
else process.env.SNAPCRAFT_STORE_CREDENTIALS = saved;
|
|
@@ -309,13 +355,13 @@ module.exports = defineCases({
|
|
|
309
355
|
},
|
|
310
356
|
},
|
|
311
357
|
{
|
|
312
|
-
name: 'baseConfig: snap
|
|
358
|
+
name: 'baseConfig: snap declared but no creds, auto-skipped',
|
|
313
359
|
run: (ctx) => {
|
|
314
360
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
315
361
|
const saved = process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
316
362
|
delete process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
317
363
|
try {
|
|
318
|
-
const out = baseConfig({ platforms: { linux: {
|
|
364
|
+
const out = baseConfig({ platforms: { linux: { formats: { snap: {} } } } });
|
|
319
365
|
ctx.expect(out.linux.target.find((t) => t.target === 'snap')).toBeUndefined();
|
|
320
366
|
ctx.expect(out.snap).toBeUndefined();
|
|
321
367
|
} finally {
|
|
@@ -324,13 +370,13 @@ module.exports = defineCases({
|
|
|
324
370
|
},
|
|
325
371
|
},
|
|
326
372
|
{
|
|
327
|
-
name: 'baseConfig: snap
|
|
373
|
+
name: 'baseConfig: snap dropped with `false`, no snap target regardless of creds',
|
|
328
374
|
run: (ctx) => {
|
|
329
375
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
330
376
|
const saved = process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
331
377
|
process.env.SNAPCRAFT_STORE_CREDENTIALS = 'fake-creds-blob';
|
|
332
378
|
try {
|
|
333
|
-
const out = baseConfig({ platforms: { linux: {
|
|
379
|
+
const out = baseConfig({ platforms: { linux: { formats: { snap: false } } } });
|
|
334
380
|
ctx.expect(out.linux.target.find((t) => t.target === 'snap')).toBeUndefined();
|
|
335
381
|
ctx.expect(out.snap).toBeUndefined();
|
|
336
382
|
} finally {
|
|
@@ -340,18 +386,18 @@ module.exports = defineCases({
|
|
|
340
386
|
},
|
|
341
387
|
},
|
|
342
388
|
{
|
|
343
|
-
name: 'baseConfig: snap
|
|
389
|
+
name: 'baseConfig: snap declared + creds present emits snap target + snap publish block',
|
|
344
390
|
run: (ctx) => {
|
|
345
391
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
346
392
|
const saved = process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
347
393
|
process.env.SNAPCRAFT_STORE_CREDENTIALS = 'fake-creds-blob';
|
|
348
394
|
try {
|
|
349
|
-
const out = baseConfig({ platforms: { linux: { snap: {
|
|
395
|
+
const out = baseConfig({ platforms: { linux: { formats: { snap: { channels: ['edge'] } } } } });
|
|
350
396
|
ctx.expect(out.linux.target.find((t) => t.target === 'snap')).toBeDefined();
|
|
351
397
|
ctx.expect(out.snap).toBeDefined();
|
|
352
398
|
ctx.expect(out.snap.confinement).toBe('strict');
|
|
353
399
|
ctx.expect(out.snap.publish.provider).toBe('snapStore');
|
|
354
|
-
ctx.expect(out.snap.publish.channels).toEqual(['
|
|
400
|
+
ctx.expect(out.snap.publish.channels).toEqual(['edge'], 'the format\'s own settings ride inside it');
|
|
355
401
|
} finally {
|
|
356
402
|
if (saved === undefined) delete process.env.SNAPCRAFT_STORE_CREDENTIALS;
|
|
357
403
|
else process.env.SNAPCRAFT_STORE_CREDENTIALS = saved;
|
|
@@ -364,9 +410,9 @@ module.exports = defineCases({
|
|
|
364
410
|
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
365
411
|
const out = baseConfig({
|
|
366
412
|
platforms: {
|
|
367
|
-
mac:
|
|
368
|
-
|
|
369
|
-
linux:
|
|
413
|
+
mac: { arch: ['arm64'] },
|
|
414
|
+
windows: { arch: ['x64'] },
|
|
415
|
+
linux: { arch: ['arm64'] },
|
|
370
416
|
},
|
|
371
417
|
});
|
|
372
418
|
ctx.expect(out.mac.target[0].arch).toEqual(['arm64']);
|
|
@@ -412,7 +458,7 @@ module.exports = defineCases({
|
|
|
412
458
|
// framework monorepo, and a feed baked from it would 404 forever.
|
|
413
459
|
ctx.expect(publishConfig({
|
|
414
460
|
brand: { id: 'omega-playground' },
|
|
415
|
-
repo: {
|
|
461
|
+
repo: { provider: 'github', org: 'Omega-JS-Stack' },
|
|
416
462
|
releases: {},
|
|
417
463
|
})).toEqual({
|
|
418
464
|
provider: 'github',
|
|
@@ -421,12 +467,19 @@ module.exports = defineCases({
|
|
|
421
467
|
releaseType: 'release',
|
|
422
468
|
});
|
|
423
469
|
|
|
424
|
-
//
|
|
470
|
+
// #883: `releases` is a presence switch and nothing more. The owner
|
|
471
|
+
// and repo overrides are retired, so the feed can only ever be the
|
|
472
|
+
// brand's one derived releases repo.
|
|
425
473
|
ctx.expect(publishConfig({
|
|
426
474
|
brand: { id: 'acme' },
|
|
427
|
-
repo: {
|
|
428
|
-
releases: {
|
|
429
|
-
})
|
|
475
|
+
repo: { provider: 'github', org: 'Acme-Org' },
|
|
476
|
+
releases: {},
|
|
477
|
+
})).toEqual({
|
|
478
|
+
provider: 'github',
|
|
479
|
+
owner: 'Acme-Org',
|
|
480
|
+
repo: 'acme-releases',
|
|
481
|
+
releaseType: 'release',
|
|
482
|
+
});
|
|
430
483
|
},
|
|
431
484
|
},
|
|
432
485
|
{
|
|
@@ -436,7 +489,7 @@ module.exports = defineCases({
|
|
|
436
489
|
|
|
437
490
|
ctx.expect(publishConfig({
|
|
438
491
|
brand: { id: 'acme' },
|
|
439
|
-
repo: {
|
|
492
|
+
repo: { provider: 'github', org: 'Acme-Org' },
|
|
440
493
|
releases: { enabled: false },
|
|
441
494
|
})).toBe(null);
|
|
442
495
|
|
|
@@ -453,5 +506,62 @@ module.exports = defineCases({
|
|
|
453
506
|
ctx.expect(out.protocols).toBeUndefined();
|
|
454
507
|
},
|
|
455
508
|
},
|
|
509
|
+
// The .deb target's two metadata facts (#872). electron-builder reads the
|
|
510
|
+
// homepage off the app package.json (`extraMetadata` is what it merges in) and
|
|
511
|
+
// the maintainer off `linux.maintainer`; without them the deb build dies at
|
|
512
|
+
// PACKAGE time, after the AppImage of the same run has already uploaded.
|
|
513
|
+
{
|
|
514
|
+
name: 'baseConfig: the brand url and support email become the deb metadata (#872)',
|
|
515
|
+
run: (ctx) => {
|
|
516
|
+
const { baseConfig } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
517
|
+
const yaml = require('js-yaml');
|
|
518
|
+
|
|
519
|
+
const out = baseConfig({
|
|
520
|
+
brand: {
|
|
521
|
+
name: 'OMEGA Playground',
|
|
522
|
+
url: 'https://playground.omegajs.dev',
|
|
523
|
+
contact: { email: 'support@playground.omegajs.dev' },
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
ctx.expect(out.extraMetadata.homepage).toBe('https://playground.omegajs.dev');
|
|
528
|
+
ctx.expect(out.linux.maintainer).toBe('OMEGA Playground <support@playground.omegajs.dev>');
|
|
529
|
+
|
|
530
|
+
// And they survive into the file that is actually written.
|
|
531
|
+
const written = yaml.load(yaml.dump(out, { lineWidth: -1, noRefs: true }));
|
|
532
|
+
ctx.expect(written.extraMetadata.homepage).toBe('https://playground.omegajs.dev');
|
|
533
|
+
ctx.expect(written.linux.maintainer).toBe('OMEGA Playground <support@playground.omegajs.dev>');
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: 'assertLinuxPackageMetadata: an absent value names its config key and never writes an empty one',
|
|
538
|
+
run: async (ctx) => {
|
|
539
|
+
const { baseConfig, assertLinuxPackageMetadata } = require(path.join(__dirname, '..', '..', '..', 'gulp', 'tasks', 'build-config.js'));
|
|
540
|
+
|
|
541
|
+
const bare = baseConfig({});
|
|
542
|
+
// Nothing to derive, so nothing is emitted: no `maintainer: ''` in the yml.
|
|
543
|
+
ctx.expect('extraMetadata' in bare).toBe(false);
|
|
544
|
+
ctx.expect('maintainer' in bare.linux).toBe(false);
|
|
545
|
+
|
|
546
|
+
await ctx.expect(() => assertLinuxPackageMetadata(bare)).toThrow(/brand\.url/);
|
|
547
|
+
await ctx.expect(() => assertLinuxPackageMetadata(bare)).toThrow(/brand\.contact\.email/);
|
|
548
|
+
|
|
549
|
+
// Only the missing half is named.
|
|
550
|
+
const noEmail = baseConfig({ brand: { name: 'App', url: 'https://app.example.com' } });
|
|
551
|
+
await ctx.expect(() => assertLinuxPackageMetadata(noEmail)).toThrow(/brand\.contact\.email/);
|
|
552
|
+
ctx.expect(noEmail.extraMetadata.homepage).toBe('https://app.example.com');
|
|
553
|
+
|
|
554
|
+
// A consumer override of `linux.maintainer` satisfies it, which is why the
|
|
555
|
+
// assert runs after the electronBuilder merge and not inside baseConfig.
|
|
556
|
+
const overridden = baseConfig({ brand: { name: 'App', url: 'https://app.example.com' } });
|
|
557
|
+
overridden.linux.maintainer = 'App Team <team@app.example.com>';
|
|
558
|
+
assertLinuxPackageMetadata(overridden);
|
|
559
|
+
|
|
560
|
+
// And a build with no deb target has nothing to check.
|
|
561
|
+
const noDeb = baseConfig({});
|
|
562
|
+
noDeb.linux.target = [{ target: 'AppImage', arch: ['x64'] }];
|
|
563
|
+
assertLinuxPackageMetadata(noDeb);
|
|
564
|
+
},
|
|
565
|
+
},
|
|
456
566
|
],
|
|
457
567
|
});
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// Build-layer tests for what the build bakes as OMEGA_BUILD_JSON
|
|
2
|
+
// ([#894](https://github.com/Omega-JS-Stack/omega/issues/894),
|
|
3
|
+
// [#743](https://github.com/Omega-JS-Stack/omega/issues/743)).
|
|
4
|
+
//
|
|
5
|
+
// One wrapper and one name on every surface: `{ config, package, mode, license,
|
|
6
|
+
// builtAt }`. What differs is WHO reads it, and how it is delivered:
|
|
7
|
+
//
|
|
8
|
+
// main / preload the RESOLVED config, whole, as an esbuild `define` plus the
|
|
9
|
+
// banner. The main process boots from it (main.js reads
|
|
10
|
+
// OMEGA_BUILD_JSON.config in a packaged app, where
|
|
11
|
+
// config/omega.json5 is inside the asar), so autoUpdate,
|
|
12
|
+
// platforms, startup and the rest have to be there. Both are
|
|
13
|
+
// Node, neither is a public surface.
|
|
14
|
+
// renderer the browser-safe subset (@omega.js/config's clientConfig),
|
|
15
|
+
// delivered as the ONE `dist/build.js` every view's shell
|
|
16
|
+
// loads ahead of its bundle: the same file, the same shape and
|
|
17
|
+
// the same load order web and the extension use. A renderer is
|
|
18
|
+
// a public surface, its bundle is readable from DevTools, so
|
|
19
|
+
// the GCP account facts and the brand's provisioning sections
|
|
20
|
+
// must not be in it.
|
|
21
|
+
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
const os = require('os');
|
|
25
|
+
const vm = require('vm');
|
|
26
|
+
const defineCases = require('../../../vendor/devkit/test/define-cases.js');
|
|
27
|
+
|
|
28
|
+
const FRAMEWORK_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
|
29
|
+
const SRC = path.join(FRAMEWORK_ROOT, 'src');
|
|
30
|
+
const TASK = path.join(SRC, 'gulp', 'tasks', 'bundle.js');
|
|
31
|
+
const PAGE_TEMPLATE = path.join(SRC, 'config', 'page-template.html');
|
|
32
|
+
|
|
33
|
+
// A resolved desktop config with one section from each side of the gate.
|
|
34
|
+
const CONFIG = () => ({
|
|
35
|
+
brand: { id: 'paperloom', name: 'Paperloom' },
|
|
36
|
+
theme: { id: 'classy' },
|
|
37
|
+
cloud: {
|
|
38
|
+
provider: 'firebase',
|
|
39
|
+
config: { apiKey: 'public-web-key', projectId: 'paperloom-prod' },
|
|
40
|
+
billingAccount: '01ABCD-234567-89EFGH',
|
|
41
|
+
},
|
|
42
|
+
app: { productName: 'Paperloom' },
|
|
43
|
+
platforms: { windows: { signing: 'cloud' } },
|
|
44
|
+
certificates: { providers: { apple: { teamId: 'TEAM' } } },
|
|
45
|
+
account: { admins: [{ email: 'root@paperloom.com' }] },
|
|
46
|
+
repo: { provider: 'github', org: 'Paperloom' },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const MODE = { environment: 'production', build: true, publish: false, server: false };
|
|
50
|
+
|
|
51
|
+
const INPUT = () => {
|
|
52
|
+
const { buildFacts } = require(TASK);
|
|
53
|
+
const pkg = { name: 'paperloom', version: '3.1.4' };
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
config: CONFIG(),
|
|
57
|
+
facts: buildFacts({ pkg, mode: MODE, dev: { ports: { backend: 5002 } } }),
|
|
58
|
+
pkg,
|
|
59
|
+
mode: MODE,
|
|
60
|
+
license: { status: 'licensed', payments: 'live', attribution: 'removed' },
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Run a `build.js` the way a browser does: a scope whose only global is `self`.
|
|
65
|
+
function loadBuildJs(file) {
|
|
66
|
+
const scope = { self: {} };
|
|
67
|
+
vm.runInNewContext(fs.readFileSync(file, 'utf8'), scope);
|
|
68
|
+
return scope.self.OMEGA_BUILD_JSON;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Stage a minimal desktop project and run the REAL bundle task in it: the task
|
|
72
|
+
// reads its project (package.json / config / dist) from cwd at require time.
|
|
73
|
+
async function inStagedProject(fn) {
|
|
74
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-build-json-'));
|
|
75
|
+
fs.writeFileSync(path.join(tmp, 'package.json'), '{ "name": "staged-desktop", "version": "3.1.4" }');
|
|
76
|
+
fs.mkdirSync(path.join(tmp, 'config'), { recursive: true });
|
|
77
|
+
fs.writeFileSync(path.join(tmp, 'config', 'omega.json5'), `{
|
|
78
|
+
brand: { id: 'staged', name: 'Staged' },
|
|
79
|
+
cloud: { config: { apiKey: 'AIza-staged', projectId: 'demo-staged' }, billingAccount: '01ABCD-234567-89EFGH' },
|
|
80
|
+
targets: { desktop: { type: 'desktop' } },
|
|
81
|
+
}`);
|
|
82
|
+
|
|
83
|
+
const write = (relative, contents) => {
|
|
84
|
+
const full = path.join(tmp, relative);
|
|
85
|
+
fs.mkdirSync(path.dirname(full), { recursive: true });
|
|
86
|
+
fs.writeFileSync(full, contents);
|
|
87
|
+
};
|
|
88
|
+
write('src/main.js', 'globalThis.__main = OMEGA_BUILD_JSON.config.brand.id;\n');
|
|
89
|
+
write('src/preload.js', 'globalThis.__preload = OMEGA_BUILD_JSON.config.brand.id;\n');
|
|
90
|
+
write('src/assets/js/components/main/index.js', [
|
|
91
|
+
'try { globalThis.__fromWindow = window.OMEGA_BUILD_JSON.config.brand.id; } catch (e) { globalThis.__fromWindow = null; }',
|
|
92
|
+
'',
|
|
93
|
+
].join('\n'));
|
|
94
|
+
|
|
95
|
+
const oldCwd = process.cwd();
|
|
96
|
+
const flush = () => {
|
|
97
|
+
for (const key of Object.keys(require.cache)) {
|
|
98
|
+
if (key.startsWith(SRC + path.sep)) delete require.cache[key];
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
flush();
|
|
103
|
+
try {
|
|
104
|
+
process.chdir(tmp);
|
|
105
|
+
const task = require(TASK);
|
|
106
|
+
await new Promise((resolve, reject) => task((error) => (error ? reject(error) : resolve())));
|
|
107
|
+
return await fn(tmp);
|
|
108
|
+
} finally {
|
|
109
|
+
process.chdir(oldCwd);
|
|
110
|
+
flush();
|
|
111
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = defineCases({
|
|
116
|
+
type: 'suite',
|
|
117
|
+
layer: 'build',
|
|
118
|
+
description: 'build json bake: one wrapper, one dist/build.js for the renderer (#894, #743)',
|
|
119
|
+
timeout: 180000,
|
|
120
|
+
tests: [
|
|
121
|
+
{
|
|
122
|
+
name: 'the wrapper is { config, package, mode, license, builtAt } on both halves',
|
|
123
|
+
run: (ctx) => {
|
|
124
|
+
const { composeBuildJson, composeClientBuildJson } = require(TASK);
|
|
125
|
+
|
|
126
|
+
const input = INPUT();
|
|
127
|
+
const buildJson = composeBuildJson(input);
|
|
128
|
+
const clientJson = composeClientBuildJson(input);
|
|
129
|
+
|
|
130
|
+
for (const blob of [buildJson, clientJson]) {
|
|
131
|
+
ctx.expect(Object.keys(blob).sort()).toEqual(['builtAt', 'config', 'license', 'mode', 'package']);
|
|
132
|
+
ctx.expect(blob.package.version).toBe('3.1.4');
|
|
133
|
+
ctx.expect(blob.license.status).toBe('licensed');
|
|
134
|
+
ctx.expect(typeof blob.builtAt).toBe('string');
|
|
135
|
+
// The mode is the same THREE keys everywhere (#894): desktop's own
|
|
136
|
+
// `server` verdict stays inside the Manager.
|
|
137
|
+
ctx.expect(Object.keys(blob.mode).sort()).toEqual(['build', 'environment', 'publish']);
|
|
138
|
+
ctx.expect(blob.mode.environment).toBe('production');
|
|
139
|
+
ctx.expect(blob.mode.build).toBe(true);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'main and preload keep the WHOLE resolved config: the main process boots from it',
|
|
145
|
+
run: (ctx) => {
|
|
146
|
+
const { composeBuildJson } = require(TASK);
|
|
147
|
+
|
|
148
|
+
const buildJson = composeBuildJson(INPUT());
|
|
149
|
+
|
|
150
|
+
ctx.expect(buildJson.config.platforms.windows.signing).toBe('cloud');
|
|
151
|
+
ctx.expect(buildJson.config.certificates.providers.apple.teamId).toBe('TEAM');
|
|
152
|
+
ctx.expect(buildJson.config.cloud.billingAccount).toBe('01ABCD-234567-89EFGH');
|
|
153
|
+
// Plus the build facts main reads off it
|
|
154
|
+
ctx.expect(buildJson.config.version).toBe('3.1.4');
|
|
155
|
+
ctx.expect(buildJson.config.dev.ports.backend).toBe(5002);
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'the RENDERER snapshot carries the client subset, and no credential section at all',
|
|
160
|
+
run: (ctx) => {
|
|
161
|
+
const { composeClientBuildJson } = require(TASK);
|
|
162
|
+
|
|
163
|
+
const clientJson = composeClientBuildJson(INPUT());
|
|
164
|
+
|
|
165
|
+
// What the renderer's @omega.js/client actually boots from
|
|
166
|
+
ctx.expect(clientJson.config.brand.id).toBe('paperloom');
|
|
167
|
+
ctx.expect(clientJson.config.theme.id).toBe('classy');
|
|
168
|
+
ctx.expect(clientJson.config.cloud.config.apiKey).toBe('public-web-key');
|
|
169
|
+
ctx.expect(clientJson.config.app.productName).toBe('Paperloom');
|
|
170
|
+
ctx.expect(clientJson.config.version).toBe('3.1.4');
|
|
171
|
+
ctx.expect(clientJson.config.dev.ports.backend).toBe(5002);
|
|
172
|
+
// The runtime is BAKED (#896): the client's own sniff has no Electron
|
|
173
|
+
// signal to find in a renderer and would answer 'web'.
|
|
174
|
+
ctx.expect(clientJson.config.runtime).toBe('electron');
|
|
175
|
+
|
|
176
|
+
// …and nothing a public surface has no business carrying
|
|
177
|
+
ctx.expect(clientJson.config.platforms).toBeUndefined();
|
|
178
|
+
ctx.expect(clientJson.config.certificates).toBeUndefined();
|
|
179
|
+
ctx.expect(clientJson.config.account).toBeUndefined();
|
|
180
|
+
ctx.expect(clientJson.config.repo).toBeUndefined();
|
|
181
|
+
ctx.expect(clientJson.config.cloud.billingAccount).toBeUndefined();
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
// The load order the renderer depends on: the shell's FIRST script is the
|
|
186
|
+
// snapshot, ahead of the view's own bundle. `../../build.js` from
|
|
187
|
+
// dist/views/<view>/ is dist/build.js, and a packaged app resolves it
|
|
188
|
+
// inside the asar exactly as the bundle tag beside it does.
|
|
189
|
+
name: 'the page template loads build.js as its first script, ahead of the view bundle (#743)',
|
|
190
|
+
run: (ctx) => {
|
|
191
|
+
const template = fs.readFileSync(PAGE_TEMPLATE, 'utf8');
|
|
192
|
+
const loader = template.indexOf('<script src="../../build.js');
|
|
193
|
+
const bundle = template.indexOf('<script src="../../assets/js/components/');
|
|
194
|
+
|
|
195
|
+
ctx.expect(loader > -1).toBe(true);
|
|
196
|
+
ctx.expect(bundle > loader).toBe(true);
|
|
197
|
+
// The FIRST script tag in the shell, full stop.
|
|
198
|
+
ctx.expect(template.indexOf('<script')).toBe(loader);
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
name: 'a real build writes ONE dist/build.js, and the renderer bundle carries no copy (#743)',
|
|
203
|
+
run: async (ctx) => {
|
|
204
|
+
await inStagedProject(async (tmp) => {
|
|
205
|
+
const loader = path.join(tmp, 'dist', 'build.js');
|
|
206
|
+
ctx.expect(fs.existsSync(loader)).toBe(true);
|
|
207
|
+
|
|
208
|
+
const buildJson = loadBuildJs(loader);
|
|
209
|
+
ctx.expect(buildJson.config.brand.id).toBe('staged');
|
|
210
|
+
ctx.expect(buildJson.config.runtime).toBe('electron');
|
|
211
|
+
ctx.expect(buildJson.config.cloud.config.apiKey).toBe('AIza-staged');
|
|
212
|
+
// The subset gate ran: a provisioning fact never reaches the file a
|
|
213
|
+
// renderer (and anyone with DevTools) reads.
|
|
214
|
+
ctx.expect(buildJson.config.cloud.billingAccount).toBeUndefined();
|
|
215
|
+
|
|
216
|
+
// The renderer bundle carries neither the banner nor the define: with
|
|
217
|
+
// no build.js loaded there is no snapshot in that scope at all.
|
|
218
|
+
const rendererBundle = path.join(tmp, 'dist', 'assets', 'js', 'components', 'main.bundle.js');
|
|
219
|
+
const source = fs.readFileSync(rendererBundle, 'utf8');
|
|
220
|
+
ctx.expect(source.includes('OMEGA_BUILD_JSON={')).toBe(false);
|
|
221
|
+
ctx.expect(source.includes('OMEGA_BUILD_JSON = {')).toBe(false);
|
|
222
|
+
|
|
223
|
+
const scope = { self: {} };
|
|
224
|
+
scope.window = scope.self;
|
|
225
|
+
vm.runInNewContext(source, scope);
|
|
226
|
+
ctx.expect(scope.__fromWindow).toBe(null);
|
|
227
|
+
|
|
228
|
+
// Loaded the way a view loads it, build.js first, it answers.
|
|
229
|
+
const loaded = { self: {} };
|
|
230
|
+
loaded.window = loaded.self;
|
|
231
|
+
vm.runInNewContext(fs.readFileSync(loader, 'utf8'), loaded);
|
|
232
|
+
vm.runInNewContext(source, loaded);
|
|
233
|
+
ctx.expect(loaded.__fromWindow).toBe('staged');
|
|
234
|
+
|
|
235
|
+
// main and preload still carry the WHOLE config as a define: they are
|
|
236
|
+
// Node, and a packaged main boots from it inside the asar.
|
|
237
|
+
const mainBundle = fs.readFileSync(path.join(tmp, 'dist', 'main.bundle.js'), 'utf8');
|
|
238
|
+
ctx.expect(mainBundle.includes('OMEGA_BUILD_JSON')).toBe(true);
|
|
239
|
+
ctx.expect(mainBundle.includes('01ABCD-234567-89EFGH')).toBe(true);
|
|
240
|
+
ctx.expect(fs.existsSync(path.join(tmp, 'dist', 'preload.bundle.js'))).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
});
|