@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.
Files changed (345) hide show
  1. package/README.md +53 -48
  2. package/dist/assets/css/core/_initialize.scss +1 -1
  3. package/dist/assets/js/core/app-shell.js +14 -15
  4. package/dist/assets/themes/_template/_theme.js +6 -6
  5. package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
  6. package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
  7. package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
  8. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
  9. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
  10. package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
  11. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
  12. package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
  13. package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
  14. package/dist/assets/themes/base/_theme.js +4 -3
  15. package/dist/assets/themes/bootstrap/_theme.js +2 -2
  16. package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
  17. package/dist/assets/themes/classy/_theme.js +8 -6
  18. package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
  19. package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
  20. package/dist/assets/themes/neobrutalism/_theme.js +5 -5
  21. package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
  22. package/dist/assets/themes/newsflash/_theme.js +6 -6
  23. package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
  24. package/dist/build.js +87 -111
  25. package/dist/cli-run.js +4 -1
  26. package/dist/cli.js +3 -3
  27. package/dist/commands/build.js +2 -2
  28. package/dist/commands/cdp/capture.js +2 -2
  29. package/dist/commands/cdp/client.js +1 -1
  30. package/dist/commands/cdp/quit.js +2 -2
  31. package/dist/commands/cdp/relaunch.js +2 -2
  32. package/dist/commands/cdp/theme.js +1 -1
  33. package/dist/commands/cdp.js +1 -1
  34. package/dist/commands/clean.js +4 -5
  35. package/dist/commands/deploy.js +4 -4
  36. package/dist/commands/dev.js +25 -0
  37. package/dist/commands/finalize-release.js +4 -4
  38. package/dist/commands/launch.js +2 -2
  39. package/dist/commands/lib/deploy-precheck.js +3 -3
  40. package/dist/commands/lib/ensure-target.js +18 -23
  41. package/dist/commands/lib/migrate.js +17 -0
  42. package/dist/commands/logs.js +1 -1
  43. package/dist/commands/package.js +2 -2
  44. package/dist/commands/publish.js +2 -2
  45. package/dist/commands/release.js +4 -4
  46. package/dist/commands/runner.js +11 -11
  47. package/dist/commands/sign-windows.js +5 -5
  48. package/dist/commands/test.js +8 -8
  49. package/dist/commands/update.js +7 -6
  50. package/dist/commands/validate-certs.js +4 -4
  51. package/dist/commands/version.js +3 -3
  52. package/dist/defaults/.github/workflows/build.yml +18 -18
  53. package/dist/defaults/_.gitignore +0 -2
  54. package/dist/defaults/_mas/README.md +3 -3
  55. package/dist/defaults/config/certs/README.md +1 -1
  56. package/dist/defaults/config/omega.json5 +43 -43
  57. package/dist/defaults/docs/README.md +3 -3
  58. package/dist/defaults/gulpfile.js +1 -1
  59. package/dist/defaults/hooks/build/post.js +2 -2
  60. package/dist/defaults/hooks/build/pre.js +2 -2
  61. package/dist/defaults/hooks/deploy/pre.js +1 -1
  62. package/dist/defaults/hooks/notarize/post.js +2 -2
  63. package/dist/defaults/hooks/release/post.js +2 -2
  64. package/dist/defaults/hooks/release/pre.js +2 -2
  65. package/dist/defaults/src/assets/js/components/about/index.js +3 -5
  66. package/dist/defaults/src/assets/js/components/main/index.js +3 -5
  67. package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
  68. package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
  69. package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
  70. package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
  71. package/dist/defaults/src/integrations/context-menu/index.js +13 -13
  72. package/dist/defaults/src/integrations/menu/index.js +8 -8
  73. package/dist/defaults/src/integrations/tray/index.js +12 -12
  74. package/dist/defaults/src/main.js +5 -7
  75. package/dist/defaults/src/preload.js +4 -6
  76. package/dist/defaults/test/README.md +5 -5
  77. package/dist/defaults/test/_init.js +1 -1
  78. package/dist/gulp/main.js +9 -10
  79. package/dist/gulp/tasks/audit.js +11 -14
  80. package/dist/gulp/tasks/build-config.js +8 -8
  81. package/dist/gulp/tasks/bundle.js +16 -16
  82. package/dist/gulp/tasks/defaults.js +3 -3
  83. package/dist/gulp/tasks/distribute.js +2 -2
  84. package/dist/gulp/tasks/html.js +9 -9
  85. package/dist/gulp/tasks/package-quick.js +3 -3
  86. package/dist/gulp/tasks/package.js +3 -3
  87. package/dist/gulp/tasks/release.js +3 -3
  88. package/dist/gulp/tasks/sass.js +6 -6
  89. package/dist/gulp/tasks/serve.js +4 -4
  90. package/dist/hooks/notarize-artifacts.js +1 -1
  91. package/dist/hooks/notarize.js +1 -1
  92. package/dist/index.js +5 -8
  93. package/dist/lib/_environment-mixin.js +50 -0
  94. package/dist/lib/_lifecycle-mixin.js +45 -0
  95. package/dist/lib/analytics.js +33 -35
  96. package/dist/lib/app-state.js +14 -14
  97. package/dist/lib/auth-flow.js +18 -18
  98. package/dist/lib/auth-persistence.js +12 -12
  99. package/dist/lib/auth.js +421 -0
  100. package/dist/lib/auto-updater.js +49 -49
  101. package/dist/lib/context-menu.js +13 -13
  102. package/dist/lib/context.js +19 -19
  103. package/dist/lib/deep-link.js +34 -34
  104. package/dist/lib/fontawesome.js +5 -5
  105. package/dist/lib/ipc.js +4 -4
  106. package/dist/lib/menu.js +25 -25
  107. package/dist/lib/protocol.js +5 -5
  108. package/dist/lib/remote-config.js +22 -22
  109. package/dist/lib/remote-scripts.js +21 -21
  110. package/dist/lib/restart-manager/index.js +29 -29
  111. package/dist/lib/restart-manager/install.js +1 -1
  112. package/dist/lib/restart-manager/protocol.js +1 -1
  113. package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
  114. package/dist/lib/sign-helpers/sign-events.js +1 -1
  115. package/dist/lib/startup.js +18 -13
  116. package/dist/lib/storage.js +10 -10
  117. package/dist/lib/templating.js +16 -16
  118. package/dist/lib/theme.js +10 -10
  119. package/dist/lib/tray.js +27 -27
  120. package/dist/lib/usage.js +11 -11
  121. package/dist/lib/window-manager.js +26 -26
  122. package/dist/main.js +399 -483
  123. package/dist/preload.js +236 -176
  124. package/dist/renderer.js +417 -391
  125. package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
  126. package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
  127. package/dist/test/fixtures/consumer-app/src/main.js +5 -7
  128. package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
  129. package/dist/test/harness/boot-entry.js +22 -20
  130. package/dist/test/harness/main-entry.js +31 -30
  131. package/dist/test/harness/renderer-entry.js +5 -5
  132. package/dist/test/harness/renderer-preload.js +137 -141
  133. package/dist/test/index.js +10 -10
  134. package/dist/test/runner.js +2 -2
  135. package/dist/test/runners/boot.js +7 -6
  136. package/dist/test/runners/electron.js +3 -2
  137. package/dist/test/runners/render-event.js +2 -2
  138. package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
  139. package/dist/test/suites/boot/restart-manager.test.js +2 -2
  140. package/dist/test/suites/boot/storage-bundled.test.js +5 -5
  141. package/dist/test/suites/boot/theme.test.js +13 -13
  142. package/dist/test/suites/build/audit.test.js +21 -8
  143. package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
  144. package/dist/test/suites/build/boot-fixture.test.js +2 -2
  145. package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
  146. package/dist/test/suites/build/brand-scss.test.js +1 -1
  147. package/dist/test/suites/build/build-json-bake.test.js +1 -1
  148. package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
  149. package/dist/test/suites/build/cli.test.js +30 -2
  150. package/dist/test/suites/build/config-schema.test.js +5 -5
  151. package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
  152. package/dist/test/suites/build/defaults-scaffold.test.js +21 -7
  153. package/dist/test/suites/build/deploy-direct.test.js +7 -5
  154. package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
  155. package/dist/test/suites/build/deploy-hook.test.js +7 -5
  156. package/dist/test/suites/build/dev-verb.test.js +67 -0
  157. package/dist/test/suites/build/ensure-target.test.js +13 -5
  158. package/dist/test/suites/build/env-delivery.test.js +2 -2
  159. package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
  160. package/dist/test/suites/build/exports.test.js +9 -8
  161. package/dist/test/suites/build/get-config.test.js +4 -4
  162. package/dist/test/suites/build/manifest-deps.test.js +1 -1
  163. package/dist/test/suites/build/merge-line-files.test.js +7 -7
  164. package/dist/test/suites/build/migrate.test.js +29 -0
  165. package/dist/test/suites/build/omega-shell.test.js +34 -2
  166. package/dist/test/suites/build/omega.test.js +350 -0
  167. package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
  168. package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
  169. package/dist/test/suites/build/runner-env-write.test.js +73 -0
  170. package/dist/test/suites/build/runner.test.js +11 -10
  171. package/dist/test/suites/build/sentry.test.js +2 -2
  172. package/dist/test/suites/build/setup-scripts.test.js +27 -0
  173. package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
  174. package/dist/test/suites/build/templating.test.js +3 -3
  175. package/dist/test/suites/build/test-stealth.test.js +7 -9
  176. package/dist/test/suites/build/url-helpers.test.js +55 -56
  177. package/dist/test/suites/build/validate-config.test.js +15 -4
  178. package/dist/test/suites/build/verb-logs.test.js +20 -0
  179. package/dist/test/suites/build/wave5-pins.test.js +2 -2
  180. package/dist/test/suites/main/analytics.test.js +59 -59
  181. package/dist/test/suites/main/app-state.test.js +66 -66
  182. package/dist/test/suites/main/auth-flow.test.js +41 -41
  183. package/dist/test/suites/main/auth-persistence.test.js +54 -43
  184. package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
  185. package/dist/test/suites/main/auth.test.js +336 -0
  186. package/dist/test/suites/main/auto-updater.test.js +134 -134
  187. package/dist/test/suites/main/boot-sequence.test.js +37 -49
  188. package/dist/test/suites/main/context-menu.test.js +51 -50
  189. package/dist/test/suites/main/context.test.js +25 -25
  190. package/dist/test/suites/main/deep-link.test.js +74 -74
  191. package/dist/test/suites/main/fontawesome.test.js +27 -27
  192. package/dist/test/suites/main/ipc.test.js +35 -35
  193. package/dist/test/suites/main/menu.test.js +101 -100
  194. package/dist/test/suites/main/protocol.test.js +19 -19
  195. package/dist/test/suites/main/remote-config.test.js +63 -63
  196. package/dist/test/suites/main/remote-scripts.test.js +103 -103
  197. package/dist/test/suites/main/request.test.js +71 -0
  198. package/dist/test/suites/main/restart-manager.test.js +33 -33
  199. package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
  200. package/dist/test/suites/main/startup.test.js +26 -26
  201. package/dist/test/suites/main/stealth-window.test.js +1 -1
  202. package/dist/test/suites/main/storage.test.js +25 -25
  203. package/dist/test/suites/main/theme.test.js +34 -34
  204. package/dist/test/suites/main/tray.test.js +79 -79
  205. package/dist/test/suites/main/url-helpers.test.js +133 -133
  206. package/dist/test/suites/main/usage.test.js +25 -25
  207. package/dist/test/suites/main/window-bounds.test.js +27 -27
  208. package/dist/test/suites/main/window-manager.test.js +44 -44
  209. package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
  210. package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
  211. package/dist/test/suites/renderer/round-trip.test.js +3 -3
  212. package/dist/test/suites/renderer/tooltips.test.js +15 -15
  213. package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +28 -8
  214. package/dist/test/utils/extended-mode-warning.js +1 -1
  215. package/dist/utils/boot-harness.js +56 -0
  216. package/dist/utils/build-pipeline.js +4 -4
  217. package/dist/utils/mode-helpers.js +2 -15
  218. package/dist/utils/runner-env.js +13 -28
  219. package/dist/utils/ship-keys.js +3 -3
  220. package/dist/utils/signing-status.js +51 -0
  221. package/dist/utils/test-events.js +7 -0
  222. package/dist/utils/test-stealth.js +6 -6
  223. package/dist/utils/url-helpers.js +52 -42
  224. package/dist/utils/user-agent.js +44 -0
  225. package/dist/vendor/account/engine.js +3 -3
  226. package/dist/vendor/account/index.js +14 -45
  227. package/dist/vendor/account/resolve-account.js +44 -0
  228. package/dist/vendor/account/schema.js +1 -1
  229. package/dist/vendor/account/user.js +99 -0
  230. package/dist/vendor/config/client-config.js +1 -1
  231. package/dist/vendor/config/company.js +46 -14
  232. package/dist/vendor/config/defaults.js +30 -7
  233. package/dist/vendor/config/edit.js +25 -3
  234. package/dist/vendor/config/env-delivery.js +1 -1
  235. package/dist/vendor/config/env-schema.js +3 -6
  236. package/dist/vendor/config/env.js +34 -22
  237. package/dist/vendor/config/environment.js +11 -30
  238. package/dist/vendor/config/index.js +21 -28
  239. package/dist/vendor/config/load.js +16 -9
  240. package/dist/vendor/config/platforms.js +1 -1
  241. package/dist/vendor/config/repo.js +10 -27
  242. package/dist/vendor/config/schema-client.js +64 -0
  243. package/dist/vendor/config/schema-cloud.js +38 -0
  244. package/dist/vendor/config/schema-manager.js +118 -0
  245. package/dist/vendor/config/schema-overrides.js +68 -0
  246. package/dist/vendor/config/schema.js +104 -160
  247. package/dist/vendor/config/site-global.js +2 -3
  248. package/dist/vendor/config/validate.js +97 -78
  249. package/dist/vendor/config/winback.js +1 -1
  250. package/dist/vendor/devkit/actions-secrets.js +1 -1
  251. package/dist/vendor/devkit/agents-md.js +233 -0
  252. package/dist/vendor/devkit/attach-log-file.js +16 -2
  253. package/dist/vendor/devkit/build-json.js +1 -1
  254. package/dist/vendor/devkit/ci-workflows.js +30 -30
  255. package/dist/vendor/devkit/cli-router.js +16 -11
  256. package/dist/vendor/devkit/defaults-engine.js +15 -51
  257. package/dist/vendor/devkit/deploy-snapshot.js +44 -9
  258. package/dist/vendor/devkit/env-lines.js +183 -0
  259. package/dist/vendor/devkit/local.js +64 -10
  260. package/dist/vendor/devkit/lockfile.js +32 -13
  261. package/dist/vendor/devkit/logger.js +7 -2
  262. package/dist/vendor/devkit/merge-line-files.js +219 -177
  263. package/dist/vendor/devkit/omega-bin.js +208 -111
  264. package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
  265. package/dist/vendor/devkit/preludes/index.js +1 -0
  266. package/dist/vendor/devkit/target-picker.js +45 -0
  267. package/dist/vendor/devkit/test/dashed-files.js +37 -0
  268. package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
  269. package/dist/vendor/devkit/test/runner-core.js +6 -6
  270. package/dist/vendor/devkit/update.js +15 -15
  271. package/dist/vendor/devkit/verb-scripts.js +40 -0
  272. package/dist/vendor/devkit/verbs.js +170 -0
  273. package/dist/vendor/monitoring/env.js +2 -2
  274. package/dist/vendor/monitoring/index.js +1 -1
  275. package/dist/vendor/monitoring/main.js +1 -1
  276. package/dist/vendor/monitoring/preload.js +1 -1
  277. package/dist/vendor/monitoring/renderer.js +1 -1
  278. package/package.json +19 -26
  279. package/dist/commands/install.js +0 -37
  280. package/dist/defaults/AGENTS.md +0 -110
  281. package/dist/defaults/CLAUDE.md +0 -1
  282. package/dist/lib/client-bridge.js +0 -374
  283. package/dist/lib/logger.js +0 -4
  284. package/dist/test/suites/build/manager.test.js +0 -213
  285. package/dist/test/suites/main/client-bridge.test.js +0 -262
  286. package/dist/vendor/config/env-retired.js +0 -137
  287. package/dist/vendor/config/retired-keys.js +0 -635
  288. package/docs/analytics.md +0 -140
  289. package/docs/app-state.md +0 -92
  290. package/docs/audit.md +0 -69
  291. package/docs/auto-updater.md +0 -243
  292. package/docs/boot-sequence.md +0 -39
  293. package/docs/build-system.md +0 -169
  294. package/docs/cdp-debugging.md +0 -169
  295. package/docs/client-bridge.md +0 -269
  296. package/docs/common-mistakes.md +0 -21
  297. package/docs/config-schema.md +0 -120
  298. package/docs/context-menu.md +0 -112
  299. package/docs/context.md +0 -81
  300. package/docs/css.md +0 -90
  301. package/docs/deep-link.md +0 -186
  302. package/docs/environment-detection.md +0 -112
  303. package/docs/fontawesome.md +0 -107
  304. package/docs/hooks.md +0 -89
  305. package/docs/icons.md +0 -79
  306. package/docs/index.md +0 -317
  307. package/docs/installer-options.md +0 -165
  308. package/docs/ipc.md +0 -61
  309. package/docs/lib-modules.md +0 -53
  310. package/docs/logging.md +0 -229
  311. package/docs/menu.md +0 -160
  312. package/docs/releasing.md +0 -239
  313. package/docs/remote-config.md +0 -118
  314. package/docs/remote-scripts.md +0 -144
  315. package/docs/restart-manager.md +0 -144
  316. package/docs/runner.md +0 -290
  317. package/docs/sentry.md +0 -97
  318. package/docs/shared/agent-docs.md +0 -89
  319. package/docs/shared/analytics.md +0 -612
  320. package/docs/shared/brands.md +0 -57
  321. package/docs/shared/breaking-changes.md +0 -851
  322. package/docs/shared/config.md +0 -1952
  323. package/docs/shared/deploys.md +0 -341
  324. package/docs/shared/icons.md +0 -219
  325. package/docs/shared/local-dev.md +0 -167
  326. package/docs/shared/logging.md +0 -205
  327. package/docs/shared/monitoring.md +0 -167
  328. package/docs/shared/publishing.md +0 -187
  329. package/docs/shared/rulings.md +0 -34
  330. package/docs/shared/testing.md +0 -147
  331. package/docs/shared/theming.md +0 -629
  332. package/docs/shared/translation.md +0 -333
  333. package/docs/shared/updates.md +0 -61
  334. package/docs/signing.md +0 -293
  335. package/docs/startup.md +0 -142
  336. package/docs/storage.md +0 -59
  337. package/docs/templating.md +0 -101
  338. package/docs/test-boot-layer.md +0 -157
  339. package/docs/test-framework.md +0 -362
  340. package/docs/themes.md +0 -149
  341. package/docs/tooltips.md +0 -99
  342. package/docs/tray.md +0 -164
  343. package/docs/usage.md +0 -58
  344. package/docs/verts.md +0 -62
  345. package/docs/windows.md +0 -149
@@ -0,0 +1,350 @@
1
+ // Build-layer tests for the ONE `omega` runtime each Electron process exports
2
+ // ([#945](https://github.com/Omega-JS-Stack/omega/issues/945)), and for the
3
+ // build-time module (build.js) beside them.
4
+ //
5
+ // main.js, preload.js and renderer.js each export ONE ready-made instance as the
6
+ // module and its class as `.Omega`; a consumer never writes `new`. The renderer
7
+ // extends @omega.js/client's base class and requires the preload's bridge, so it
8
+ // is loaded here with a `window.desktop` present (and pinned to refuse to load
9
+ // without one). Everything that needs a real Electron is the main layer's.
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const build = require('../../../build.js');
14
+ const defineCases = require('../../../vendor/devkit/test/define-cases.js');
15
+
16
+ const ROOT = path.join(__dirname, '..', '..', '..');
17
+ const read = (file) => fs.readFileSync(path.join(ROOT, file), 'utf8');
18
+
19
+ /**
20
+ * Load renderer.js fresh with `window` set to `win` (null = no window at all),
21
+ * then put the globals back.
22
+ * @param {object|null} win - the window the module loads under.
23
+ * @returns {object} the module's export.
24
+ */
25
+ function loadRenderer(win) {
26
+ const file = require.resolve(path.join(ROOT, 'renderer.js'));
27
+ const saved = globalThis.window;
28
+ delete require.cache[file];
29
+ if (win) globalThis.window = win;
30
+ else delete globalThis.window;
31
+ try {
32
+ return require(file);
33
+ } finally {
34
+ delete require.cache[file];
35
+ if (saved === undefined) delete globalThis.window;
36
+ else globalThis.window = saved;
37
+ }
38
+ }
39
+
40
+ // The production preload's `window.desktop` keys, in source order
41
+ const DESKTOP_KEYS = ['environment', 'ipc', 'storage', 'theme', 'fontawesome', 'logger', 'autoUpdater', 'analytics', 'context', 'usage', 'remoteConfig'];
42
+
43
+ // The one input and the two lane flags that decide it, saved and restored
44
+ // around every case that touches them (#817).
45
+ const LANE_KEYS = ['OMEGA_ENVIRONMENT', 'OMEGA_BUILD_MODE', 'OMEGA_TEST_MODE', 'NODE_ENV'];
46
+
47
+ /**
48
+ * Run `fn` with exactly `vars` set on the lane keys (null clears them all).
49
+ * @param {object|null} vars - the lane env for this case.
50
+ * @param {function} fn - the body.
51
+ * @returns {*} whatever `fn` returns.
52
+ */
53
+ function withEnvironment(vars, fn) {
54
+ const saved = {};
55
+ for (const key of LANE_KEYS) saved[key] = process.env[key];
56
+ try {
57
+ for (const key of LANE_KEYS) delete process.env[key];
58
+ Object.assign(process.env, vars || {});
59
+ return fn();
60
+ } finally {
61
+ for (const key of LANE_KEYS) {
62
+ if (saved[key] === undefined) delete process.env[key];
63
+ else process.env[key] = saved[key];
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * What src/build.js resolves at LOAD for a given lane. build.js sets the input
70
+ * once, at require time, so this loads a fresh copy of it per lane.
71
+ * @param {object} vars - the lane env.
72
+ * @returns {string} the resolved environment.
73
+ */
74
+ function laneEnvironment(vars) {
75
+ const buildPath = require.resolve('../../../build.js');
76
+ return withEnvironment(vars, () => {
77
+ const saved = require.cache[buildPath];
78
+ delete require.cache[buildPath];
79
+ try {
80
+ return require(buildPath).getEnvironment();
81
+ } finally {
82
+ if (saved) require.cache[buildPath] = saved;
83
+ else delete require.cache[buildPath];
84
+ }
85
+ });
86
+ }
87
+
88
+ module.exports = defineCases({
89
+ type: 'group', // independent tests; run all even on failure
90
+ layer: 'build',
91
+ description: 'Omega runtimes (main, preload, renderer) + the build module (build.js)',
92
+ tests: [
93
+ {
94
+ name: 'main and preload export ONE instance each, and .Omega is its constructor',
95
+ run: (ctx) => {
96
+ for (const file of ['main.js', 'preload.js']) {
97
+ const omega = require(path.join(ROOT, file));
98
+ ctx.expect(typeof omega.Omega).toBe('function');
99
+ ctx.expect(omega).toBeInstanceOf(omega.Omega);
100
+ ctx.expect(omega.constructor).toBe(omega.Omega);
101
+ ctx.expect(typeof omega.initialize).toBe('function');
102
+ ctx.expect(omega.ready).toBeInstanceOf(Promise);
103
+ }
104
+ },
105
+ },
106
+ {
107
+ name: 'main carries every library as a plain property, `auth` among them and no `omega`',
108
+ run: (ctx) => {
109
+ const omega = require(path.join(ROOT, 'main.js'));
110
+ ctx.expect(omega.auth).toBe(require(path.join(ROOT, 'lib', 'auth.js')));
111
+ ctx.expect(omega.omega).toBeUndefined();
112
+ for (const name of ['getEnvironment', 'isDevelopment', 'isProduction', 'isTesting', 'getVersion', 'getFunctionsUrl', 'getApiUrl', 'getWebsiteUrl', 'getAuthUrl', 'openAuthFlow', 'quit', 'relaunch', 'require']) {
113
+ ctx.expect(typeof omega[name]).toBe('function');
114
+ }
115
+ ctx.expect(typeof omega.Omega.require).toBe('function');
116
+ },
117
+ },
118
+ {
119
+ name: 'preload initialize() outside a BrowserWindow settles ready with the instance',
120
+ run: async (ctx) => {
121
+ const { Omega } = require(path.join(ROOT, 'preload.js'));
122
+ const preload = new Omega();
123
+ ctx.expect(await preload.initialize()).toBe(preload);
124
+ ctx.expect(await preload.ready).toBe(preload);
125
+ },
126
+ },
127
+ {
128
+ // A window built without the framework's preload has no bridge: a
129
+ // programmer error, loud at load
130
+ name: 'renderer refuses to load without window.desktop',
131
+ run: (ctx) => {
132
+ ctx.expect(() => loadRenderer(null)).toThrow(/window\.desktop is missing/);
133
+ ctx.expect(() => loadRenderer({})).toThrow(/window\.desktop is missing/);
134
+ },
135
+ },
136
+ {
137
+ name: 'renderer exports ONE instance of a subclass of the client base, with omega.desktop the bridge',
138
+ run: async (ctx) => {
139
+ const { Omega: ClientOmega } = require('@omega.js/client');
140
+ const desktop = { ipc: {}, storage: {} };
141
+ const omega = loadRenderer({ desktop });
142
+
143
+ ctx.expect(typeof omega.Omega).toBe('function');
144
+ ctx.expect(omega).toBeInstanceOf(omega.Omega);
145
+ ctx.expect(omega).toBeInstanceOf(ClientOmega);
146
+ ctx.expect(omega.desktop).toBe(desktop);
147
+ ctx.expect(omega.storage === desktop.storage).toBe(false);
148
+ ctx.expect(omega.auth.user.constructor.name).toBe('User');
149
+ ctx.expect(omega.auth.user.authenticated).toBe(false);
150
+ for (const name of ['signOut', 'getMainUser', 'enableFontAwesome', 'getWebsiteUrl', 'getAuthUrl', 'getVersion']) {
151
+ ctx.expect(typeof omega[name]).toBe('function');
152
+ }
153
+ },
154
+ },
155
+ {
156
+ name: 'each process module defines class Omega and exports its instance (source pin)',
157
+ run: (ctx) => {
158
+ for (const file of ['main.js', 'preload.js', 'renderer.js']) {
159
+ const source = read(file);
160
+ ctx.expect(source).toMatch(/^const omega = new Omega\(\);$/m);
161
+ ctx.expect(source).toMatch(/^module\.exports = omega;$/m);
162
+ ctx.expect(source).toMatch(/^module\.exports\.Omega = Omega;$/m);
163
+ ctx.expect(source.includes('attachTo')).toBe(false);
164
+ ctx.expect(source.includes('build.prototype')).toBe(false);
165
+ }
166
+ ctx.expect(read('main.js')).toMatch(/^class Omega \{$/m);
167
+ ctx.expect(read('preload.js')).toMatch(/^class Omega \{$/m);
168
+ ctx.expect(read('renderer.js')).toMatch(/^class Omega extends ClientOmega \{$/m);
169
+ ctx.expect(read('renderer.js').includes('this.shell = createShell(this);')).toBe(true);
170
+ ctx.expect(read('main.js').includes('wmBridge')).toBe(false);
171
+ },
172
+ },
173
+ {
174
+ // The preload global keeps its name and its shape
175
+ name: 'the production preload exposes window.desktop with the same namespaces (source pin)',
176
+ run: (ctx) => {
177
+ const source = read('preload.js');
178
+ const start = source.indexOf("contextBridge.exposeInMainWorld('desktop', {");
179
+ const block = source.slice(start, source.indexOf(' });\n', start));
180
+ const keys = [...block.matchAll(/^ ([A-Za-z]+): /gm)].map((match) => match[1]);
181
+ ctx.expect(keys).toEqual(DESKTOP_KEYS);
182
+ },
183
+ },
184
+ {
185
+ // `.` is the build-time entry; each process imports its instance by subpath
186
+ name: 'the package root exports { version, build } and nothing else',
187
+ run: (ctx) => {
188
+ const root = require(path.join(ROOT, 'index.js'));
189
+ ctx.expect(Object.keys(root).sort()).toEqual(['build', 'version']);
190
+ ctx.expect(root.build).toBe(build);
191
+ },
192
+ },
193
+ {
194
+ name: 'the build module is one plain object: no class, no new',
195
+ run: (ctx) => {
196
+ ctx.expect(typeof build).toBe('object');
197
+ ctx.expect(typeof build.getConfig).toBe('function');
198
+ ctx.expect(read('build.js')).toMatch(/^module\.exports = \{$/m);
199
+ },
200
+ },
201
+ {
202
+ name: 'getMode returns the mode shape',
203
+ run: (ctx) => {
204
+ const mode = build.getMode();
205
+ ctx.expect(mode).toHaveProperty('build');
206
+ ctx.expect(mode).toHaveProperty('publish');
207
+ ctx.expect(mode).toHaveProperty('server');
208
+ ctx.expect(mode).toHaveProperty('environment');
209
+ ctx.expect(['development', 'testing', 'production']).toContain(mode.environment);
210
+ },
211
+ },
212
+ {
213
+ // The environment reads ONE input, `OMEGA_ENVIRONMENT`
214
+ // ([#817](https://github.com/Omega-JS-Stack/omega/issues/817)), and the
215
+ // lane that boots or builds this app sets it (src/build.js does, at load).
216
+ // Nothing sniffs NODE_ENV, app.isPackaged or OMEGA_TEST_MODE any more.
217
+ name: 'getEnvironment answers the one input, for each of the three names',
218
+ run: (ctx) => {
219
+ withEnvironment(null, () => {
220
+ for (const name of ['development', 'testing', 'production']) {
221
+ process.env.OMEGA_ENVIRONMENT = name;
222
+ ctx.expect(build.getEnvironment()).toBe(name);
223
+ }
224
+ });
225
+ },
226
+ },
227
+ {
228
+ // The bug this replaced: with no signal desktop's own copy answered
229
+ // 'production', so a plain `npm start` bundled itself as a production
230
+ // artifact, while @omega.js/extension's copy of the same function
231
+ // answered 'development' from the same inputs (#817).
232
+ name: 'the build lane resolves production, a dev boot resolves development',
233
+ run: (ctx) => {
234
+ const buildLane = laneEnvironment({ OMEGA_BUILD_MODE: 'true' });
235
+ ctx.expect(buildLane).toBe('production');
236
+
237
+ const devBoot = laneEnvironment({});
238
+ ctx.expect(devBoot).toBe('development');
239
+
240
+ // A lane that already named one keeps it, EXCEPT a build lane: a
241
+ // production build spawned from a test run still bakes production.
242
+ ctx.expect(laneEnvironment({ OMEGA_ENVIRONMENT: 'testing' })).toBe('testing');
243
+ ctx.expect(laneEnvironment({ OMEGA_ENVIRONMENT: 'testing', OMEGA_BUILD_MODE: 'true' })).toBe('production');
244
+ },
245
+ },
246
+ {
247
+ name: 'no input at all is a loud error naming OMEGA_ENVIRONMENT, never a default',
248
+ run: (ctx) => {
249
+ withEnvironment(null, () => {
250
+ delete process.env.OMEGA_ENVIRONMENT;
251
+ ctx.expect(() => build.getEnvironment()).toThrow(/OMEGA_ENVIRONMENT/);
252
+ process.env.OMEGA_ENVIRONMENT = 'staging';
253
+ ctx.expect(() => build.getEnvironment()).toThrow(/OMEGA_ENVIRONMENT/);
254
+ });
255
+ },
256
+ },
257
+ {
258
+ // The core invariant: is*() DERIVE from getEnvironment(), so they can
259
+ // NEVER disagree with it, and exactly one is always true.
260
+ name: 'invariant: is*() exactly matches getEnvironment() + mutually exclusive (every scenario)',
261
+ run: (ctx) => {
262
+ withEnvironment(null, () => {
263
+ for (const name of ['development', 'testing', 'production']) {
264
+ process.env.OMEGA_ENVIRONMENT = name;
265
+ const e = build.getEnvironment();
266
+ ctx.expect(e).toBe(name);
267
+ ctx.expect(build.isDevelopment()).toBe(e === 'development');
268
+ ctx.expect(build.isTesting()).toBe(e === 'testing');
269
+ ctx.expect(build.isProduction()).toBe(e === 'production');
270
+ const trueCount = [build.isDevelopment(), build.isTesting(), build.isProduction()].filter(Boolean).length;
271
+ ctx.expect(trueCount).toBe(1);
272
+ }
273
+ });
274
+ },
275
+ },
276
+ {
277
+ name: 'getPackage("main") resolves to @omega.js/desktop package.json',
278
+ run: (ctx) => {
279
+ const pkg = build.getPackage('main');
280
+ ctx.expect(pkg.name).toBe('@omega.js/desktop');
281
+ ctx.expect(pkg).toHaveProperty('version');
282
+ ctx.expect(pkg).toHaveProperty('exports');
283
+ },
284
+ },
285
+ {
286
+ name: 'getRootPath("main") returns a non-empty string',
287
+ run: (ctx) => {
288
+ const root = build.getRootPath('main');
289
+ ctx.expect(typeof root).toBe('string');
290
+ ctx.expect(root.length).toBeGreaterThan(0);
291
+ },
292
+ },
293
+ {
294
+ name: 'getLiveReloadPort defaults to 35729',
295
+ run: (ctx) => {
296
+ const prev = process.env.OMEGA_LIVERELOAD_PORT;
297
+ delete process.env.OMEGA_LIVERELOAD_PORT;
298
+ try {
299
+ ctx.expect(build.getLiveReloadPort()).toBe(35729);
300
+ } finally {
301
+ if (prev !== undefined) process.env.OMEGA_LIVERELOAD_PORT = prev;
302
+ }
303
+ },
304
+ },
305
+ {
306
+ name: 'getWindowsSignStrategy defaults to self-hosted when no config',
307
+ run: (ctx) => {
308
+ // Config is the only source of the strategy: no env var sets it.
309
+ // Run from a cwd with no omega.json5 to confirm the default.
310
+ const fs = require('fs'); const os = require('os'); const path = require('path');
311
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-strategy-'));
312
+ const orig = process.cwd();
313
+ try {
314
+ process.chdir(tmp);
315
+ ctx.expect(build.getWindowsSignStrategy()).toBe('self-hosted');
316
+ } finally {
317
+ process.chdir(orig);
318
+ fs.rmSync(tmp, { recursive: true, force: true });
319
+ }
320
+ },
321
+ },
322
+ {
323
+ name: 'getWindowsSignStrategy reads config platforms.windows.signing.strategy',
324
+ run: (ctx) => {
325
+ const fs = require('fs'); const os = require('os'); const path = require('path');
326
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-strategy-'));
327
+ fs.mkdirSync(path.join(tmp, 'config'), { recursive: true });
328
+ fs.writeFileSync(path.join(tmp, 'config', 'omega.json5'),
329
+ `{ targets: { desktop: { type: 'desktop', platforms: { windows: { signing: { strategy: 'cloud' } } } } } }`);
330
+ const orig = process.cwd();
331
+ try {
332
+ process.chdir(tmp);
333
+ ctx.expect(build.getWindowsSignStrategy()).toBe('cloud');
334
+ } finally {
335
+ process.chdir(orig);
336
+ fs.rmSync(tmp, { recursive: true, force: true });
337
+ }
338
+ },
339
+ },
340
+ {
341
+ name: 'logger returns a named logger',
342
+ run: (ctx) => {
343
+ const logger = build.logger('test-name');
344
+ ctx.expect(logger.name).toBe('test-name');
345
+ ctx.expect(typeof logger.log).toBe('function');
346
+ ctx.expect(typeof logger.error).toBe('function');
347
+ },
348
+ },
349
+ ],
350
+ });
@@ -13,6 +13,7 @@
13
13
  const path = require('path');
14
14
  const fs = require('fs');
15
15
  const defineCases = require('../../../vendor/devkit/test/define-cases.js');
16
+ const { projectScripts } = require('../../../vendor/devkit/verb-scripts.js');
16
17
 
17
18
  module.exports = defineCases({
18
19
  type: 'suite',
@@ -26,7 +27,7 @@ module.exports = defineCases({
26
27
  const peers = pkg.peerDependencies || {};
27
28
 
28
29
  const tools = new Set();
29
- for (const script of Object.values(pkg.projectScripts || {})) {
30
+ for (const script of Object.values(projectScripts(pkg))) {
30
31
  for (const match of String(script).matchAll(/npx\s+([a-z0-9@/_-]+)/g)) {
31
32
  const tool = match[1];
32
33
  if (tool !== 'omega' && !tool.startsWith('@omega.js/')) {
@@ -44,7 +45,7 @@ module.exports = defineCases({
44
45
  name: 'the build-mode env flags live in the CLI verbs, not in the scaffolded scripts',
45
46
  run: (ctx) => {
46
47
  const pkg = require(path.join(__dirname, '..', '..', '..', '..', 'package.json'));
47
- const scripts = pkg.projectScripts || {};
48
+ const scripts = projectScripts(pkg);
48
49
 
49
50
  for (const script of Object.values(scripts)) {
50
51
  ctx.expect(String(script).includes('cross-env')).toBe(false);
@@ -58,7 +59,9 @@ module.exports = defineCases({
58
59
  ctx.expect(scripts.build).toBe('omega build');
59
60
  ctx.expect(scripts.package).toBe('omega package');
60
61
  ctx.expect(scripts['package:quick']).toBe('omega package --quick');
61
- ctx.expect(scripts.publish).toBe('omega publish');
62
+ // A single-target command is the CLI's, reached from the brand root, never a script
63
+ ctx.expect(scripts.publish).toBe(undefined);
64
+ ctx.expect(scripts.release).toBe(undefined);
62
65
  ctx.expect(scripts['release:local']).toBe('omega publish --local');
63
66
  },
64
67
  },
@@ -79,12 +82,5 @@ module.exports = defineCases({
79
82
  ctx.expect(source.includes('cross-env')).toBe(false);
80
83
  },
81
84
  },
82
- {
83
- name: 'ensure-target syncs projectScripts unconditionally — consumers heal on the next verb',
84
- run: (ctx) => {
85
- const source = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'commands', 'lib', 'ensure-target.js'), 'utf8');
86
- ctx.expect(/project\.scripts\[key\] = package\.projectScripts\[key\]/.test(source)).toBe(true);
87
- },
88
- },
89
85
  ],
90
86
  });