@omega.js/desktop 0.1.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/LICENSE +98 -0
- package/README.md +166 -0
- package/bin/omega +2 -0
- package/bin/omega-desktop +2 -0
- package/bin/omg +2 -0
- package/dist/assets/css/core/_fontawesome.scss +146 -0
- package/dist/assets/css/core/_initialize.scss +38 -0
- package/dist/assets/css/omega-desktop.scss +39 -0
- package/dist/assets/css/shell/_index.scss +207 -0
- package/dist/assets/css/tokens/_index.scss +166 -0
- package/dist/assets/js/bootstrap.bundle.js +1 -0
- package/dist/assets/js/core/app-shell.js +136 -0
- package/dist/assets/themes/_template/README.md +115 -0
- package/dist/assets/themes/_template/_config.scss +60 -0
- package/dist/assets/themes/_template/_theme.js +14 -0
- package/dist/assets/themes/_template/_theme.scss +28 -0
- package/dist/assets/themes/_template/css/base/_root.scss +19 -0
- package/dist/assets/themes/_template/css/components/_components.scss +23 -0
- package/dist/assets/themes/base/README.md +5 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.html +33 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.json5 +33 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.scss +183 -0
- package/dist/assets/themes/base/_components/heading/masthead/component.html +22 -0
- package/dist/assets/themes/base/_components/heading/masthead/component.json5 +30 -0
- package/dist/assets/themes/base/_components/heading/section-head/component.html +18 -0
- package/dist/assets/themes/base/_components/heading/section-head/component.json5 +27 -0
- package/dist/assets/themes/base/_components/pricing/features/component.html +29 -0
- package/dist/assets/themes/base/_components/pricing/features/component.json5 +30 -0
- package/dist/assets/themes/base/_hero/orbit/index.html +30 -0
- package/dist/assets/themes/base/_hero/orbit/script.js +33 -0
- package/dist/assets/themes/base/_hero/orbit/style.scss +133 -0
- package/dist/assets/themes/base/_includes/admin/sections/sidebar.html +3 -0
- package/dist/assets/themes/base/_includes/admin/sections/topbar.html +3 -0
- package/dist/assets/themes/base/_includes/backend/sections/sidebar.html +3 -0
- package/dist/assets/themes/base/_includes/backend/sections/topbar.html +3 -0
- package/dist/assets/themes/base/_includes/frontend/components/connection-card.html +49 -0
- package/dist/assets/themes/base/_includes/frontend/components/post-card.html +54 -0
- package/dist/assets/themes/base/_includes/frontend/sections/account-connections.html +42 -0
- package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
- package/dist/assets/themes/base/_includes/frontend/sections/footer.html +154 -0
- package/dist/assets/themes/base/_includes/frontend/sections/nav.html +276 -0
- package/dist/assets/themes/base/_includes/global/sections/account.html +72 -0
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +248 -0
- package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +228 -0
- package/dist/assets/themes/base/_includes/global/sections/page-header.html +99 -0
- package/dist/assets/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
- package/dist/assets/themes/base/_layouts/admin/core/minimal.html +23 -0
- package/dist/assets/themes/base/_layouts/backend/core/base.html +57 -0
- package/dist/assets/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
- package/dist/assets/themes/base/_layouts/backend/core/minimal.html +32 -0
- package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
- package/dist/assets/themes/base/_layouts/frontend/core/base.html +31 -0
- package/dist/assets/themes/base/_layouts/frontend/core/cover.html +40 -0
- package/dist/assets/themes/base/_layouts/frontend/core/minimal.html +47 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/404.html +54 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/about.html +144 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/app.html +142 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +214 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/download.html +793 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/feedback.html +171 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/index.html +66 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/pricing.html +596 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/status.html +361 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +210 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +125 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
- package/dist/assets/themes/base/_sections/about/hero/section.html +68 -0
- package/dist/assets/themes/base/_sections/about/hero/section.json5 +58 -0
- package/dist/assets/themes/base/_sections/about/letter/section.html +60 -0
- package/dist/assets/themes/base/_sections/about/letter/section.json5 +56 -0
- package/dist/assets/themes/base/_sections/about/photo-band/section.html +24 -0
- package/dist/assets/themes/base/_sections/about/photo-band/section.json5 +23 -0
- package/dist/assets/themes/base/_sections/about/principles/section.html +17 -0
- package/dist/assets/themes/base/_sections/about/principles/section.json5 +34 -0
- package/dist/assets/themes/base/_sections/about/timeline/section.html +20 -0
- package/dist/assets/themes/base/_sections/about/timeline/section.json5 +34 -0
- package/dist/assets/themes/base/_sections/marketing/bento/section.html +91 -0
- package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +152 -0
- package/dist/assets/themes/base/_sections/marketing/cta/section.html +44 -0
- package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +47 -0
- package/dist/assets/themes/base/_sections/marketing/faq/section.html +52 -0
- package/dist/assets/themes/base/_sections/marketing/faq/section.json5 +68 -0
- package/dist/assets/themes/base/_sections/marketing/hero/section.html +349 -0
- package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +335 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
- package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
- package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +62 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.js +44 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
- package/dist/assets/themes/base/_sections/marketing/prose/section.html +22 -0
- package/dist/assets/themes/base/_sections/marketing/prose/section.json5 +41 -0
- package/dist/assets/themes/base/_sections/marketing/showcase/section.html +35 -0
- package/dist/assets/themes/base/_sections/marketing/showcase/section.json5 +52 -0
- package/dist/assets/themes/base/_sections/marketing/stats/section.html +32 -0
- package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +44 -0
- package/dist/assets/themes/base/_sections/marketing/testimonials/section.html +54 -0
- package/dist/assets/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +30 -0
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.html +7 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.js +22 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.json5 +24 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.scss +24 -0
- package/dist/assets/themes/base/_theme.js +13 -0
- package/dist/assets/themes/base/_theme.scss +4 -0
- package/dist/assets/themes/bootstrap/_theme.js +16 -0
- package/dist/assets/themes/bootstrap/_theme.scss +11 -0
- package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
- package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
- package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
- package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
- package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
- package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
- package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
- package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
- package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
- package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
- package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
- package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
- package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
- package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
- package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
- package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
- package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
- package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
- package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
- package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
- package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
- package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
- package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
- package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
- package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
- package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
- package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
- package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
- package/dist/assets/themes/bootstrap/overrides/_accordion.scss +21 -0
- package/dist/assets/themes/bootstrap/overrides/_avatars.scss +51 -0
- package/dist/assets/themes/bootstrap/overrides/_blog-images.scss +45 -0
- package/dist/assets/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
- package/dist/assets/themes/bootstrap/overrides/_color-shades.scss +25 -0
- package/dist/assets/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
- package/dist/assets/themes/bootstrap/overrides/_index.scss +30 -0
- package/dist/assets/themes/bootstrap/overrides/_links.scss +26 -0
- package/dist/assets/themes/bootstrap/overrides/_soft-colors.scss +99 -0
- package/dist/assets/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
- package/dist/assets/themes/bootstrap/overrides/_spinners.scss +22 -0
- package/dist/assets/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
- package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
- package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
- package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
- package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
- package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
- package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
- package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
- package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
- package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
- package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
- package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
- package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
- package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
- package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
- package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
- package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
- package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
- package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
- package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
- package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
- package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
- package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
- package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
- package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
- package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
- package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
- package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
- package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
- package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
- package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
- package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
- package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
- package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
- package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
- package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
- package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
- package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
- package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
- package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
- package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
- package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
- package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
- package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
- package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
- package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
- package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
- package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
- package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
- package/dist/assets/themes/classy/README.md +89 -0
- package/dist/assets/themes/classy/_config.scss +245 -0
- package/dist/assets/themes/classy/_theme.js +31 -0
- package/dist/assets/themes/classy/_theme.scss +57 -0
- package/dist/assets/themes/classy/css/app/_panels.scss +183 -0
- package/dist/assets/themes/classy/css/base/_fonts.scss +79 -0
- package/dist/assets/themes/classy/css/base/_no-raise.scss +49 -0
- package/dist/assets/themes/classy/css/base/_root.scss +113 -0
- package/dist/assets/themes/classy/css/base/_typography.scss +154 -0
- package/dist/assets/themes/classy/css/base/_utilities.scss +284 -0
- package/dist/assets/themes/classy/css/components/_alerts.scss +51 -0
- package/dist/assets/themes/classy/css/components/_badges.scss +46 -0
- package/dist/assets/themes/classy/css/components/_buttons.scss +175 -0
- package/dist/assets/themes/classy/css/components/_cards.scss +41 -0
- package/dist/assets/themes/classy/css/components/_dropdowns.scss +48 -0
- package/dist/assets/themes/classy/css/components/_forms.scss +171 -0
- package/dist/assets/themes/classy/css/components/_receipt.scss +45 -0
- package/dist/assets/themes/classy/css/layout/_footer.scss +298 -0
- package/dist/assets/themes/classy/css/layout/_general.scss +209 -0
- package/dist/assets/themes/classy/css/layout/_nav.scss +154 -0
- package/dist/assets/themes/classy/css/layout/_shell.scss +458 -0
- package/dist/assets/themes/classy/css/marketing/_bento.scss +238 -0
- package/dist/assets/themes/classy/css/marketing/_content.scss +1328 -0
- package/dist/assets/themes/classy/css/marketing/_downloads.scss +246 -0
- package/dist/assets/themes/classy/css/marketing/_hero.scss +311 -0
- package/dist/assets/themes/classy/css/marketing/_sections.scss +649 -0
- package/dist/assets/themes/classy/css/pages/404/index.scss +67 -0
- package/dist/assets/themes/classy/css/pages/_auth.scss +235 -0
- package/dist/assets/themes/classy/css/pages/admin/firebase/index.scss +22 -0
- package/dist/assets/themes/classy/css/pages/blog/[slug].scss +56 -0
- package/dist/assets/themes/classy/css/pages/cookies.scss +2 -0
- package/dist/assets/themes/classy/css/pages/dashboard/account/index.scss +31 -0
- package/dist/assets/themes/classy/css/pages/feedback/index.scss +39 -0
- package/dist/assets/themes/classy/css/pages/legal/_document.scss +192 -0
- package/dist/assets/themes/classy/css/pages/payment/checkout/index.scss +585 -0
- package/dist/assets/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
- package/dist/assets/themes/classy/css/pages/privacy.scss +2 -0
- package/dist/assets/themes/classy/css/pages/status/index.scss +164 -0
- package/dist/assets/themes/classy/css/pages/terms.scss +2 -0
- package/dist/assets/themes/classy/css/pages/updates/index.scss +128 -0
- package/dist/assets/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
- package/dist/assets/themes/classy/js/hero-demo-form.js +56 -0
- package/dist/assets/themes/neobrutalism/README.md +118 -0
- package/dist/assets/themes/neobrutalism/_config.scss +139 -0
- package/dist/assets/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
- package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
- package/dist/assets/themes/neobrutalism/_theme.js +24 -0
- package/dist/assets/themes/neobrutalism/_theme.scss +61 -0
- package/dist/assets/themes/neobrutalism/css/base/_mixins.scss +46 -0
- package/dist/assets/themes/neobrutalism/css/base/_root.scss +169 -0
- package/dist/assets/themes/neobrutalism/css/base/_typography.scss +61 -0
- package/dist/assets/themes/neobrutalism/css/base/_utilities.scss +89 -0
- package/dist/assets/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
- package/dist/assets/themes/neobrutalism/css/components/_buttons.scss +148 -0
- package/dist/assets/themes/neobrutalism/css/components/_cards.scss +47 -0
- package/dist/assets/themes/neobrutalism/css/components/_forms.scss +88 -0
- package/dist/assets/themes/neobrutalism/css/components/_marketing.scss +244 -0
- package/dist/assets/themes/neobrutalism/css/layout/_general.scss +213 -0
- package/dist/assets/themes/neobrutalism/css/layout/_navigation.scss +171 -0
- package/dist/assets/themes/neobrutalism/css/pages/index.scss +203 -0
- package/dist/assets/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
- package/dist/assets/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
- package/dist/assets/themes/newsflash/README.md +117 -0
- package/dist/assets/themes/newsflash/_components/heading/lede/component.html +14 -0
- package/dist/assets/themes/newsflash/_components/heading/lede/component.json5 +23 -0
- package/dist/assets/themes/newsflash/_components/heading/rule-head/component.html +17 -0
- package/dist/assets/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
- package/dist/assets/themes/newsflash/_components/news/byline/component.html +12 -0
- package/dist/assets/themes/newsflash/_components/news/byline/component.json5 +18 -0
- package/dist/assets/themes/newsflash/_components/news/story-card/component.html +25 -0
- package/dist/assets/themes/newsflash/_components/news/story-card/component.json5 +21 -0
- package/dist/assets/themes/newsflash/_config.scss +147 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/core/base.html +51 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +39 -0
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
- package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
- package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
- package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
- package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
- package/dist/assets/themes/newsflash/_theme.js +24 -0
- package/dist/assets/themes/newsflash/_theme.scss +70 -0
- package/dist/assets/themes/newsflash/css/base/_fonts.scss +80 -0
- package/dist/assets/themes/newsflash/css/base/_mixins.scss +51 -0
- package/dist/assets/themes/newsflash/css/base/_root.scss +257 -0
- package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
- package/dist/assets/themes/newsflash/css/base/_utilities.scss +122 -0
- package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
- package/dist/assets/themes/newsflash/css/components/_billing-toggle.scss +61 -0
- package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
- package/dist/assets/themes/newsflash/css/components/_cards.scss +47 -0
- package/dist/assets/themes/newsflash/css/components/_editorial.scss +173 -0
- package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
- package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/dist/assets/themes/newsflash/css/components/_panels.scss +156 -0
- package/dist/assets/themes/newsflash/css/components/_ticker.scss +67 -0
- package/dist/assets/themes/newsflash/css/layout/_general.scss +330 -0
- package/dist/assets/themes/newsflash/css/layout/_navigation.scss +168 -0
- package/dist/assets/themes/newsflash/css/pages/404/index.scss +79 -0
- package/dist/assets/themes/newsflash/css/pages/blog/[slug].scss +186 -0
- package/dist/assets/themes/newsflash/css/pages/blog/index.scss +17 -0
- package/dist/assets/themes/newsflash/css/pages/index.scss +157 -0
- package/dist/assets/themes/newsflash/css/pages/pricing/index.scss +55 -0
- package/dist/assets/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/js/pages/blog/[slug].js +29 -0
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
- package/dist/build.js +249 -0
- package/dist/cli-run.js +34 -0
- package/dist/cli.js +49 -0
- package/dist/commands/build.js +32 -0
- package/dist/commands/cdp/capture.js +91 -0
- package/dist/commands/cdp/client.js +140 -0
- package/dist/commands/cdp/eval.js +20 -0
- package/dist/commands/cdp/quit.js +84 -0
- package/dist/commands/cdp/relaunch.js +62 -0
- package/dist/commands/cdp/shot.js +20 -0
- package/dist/commands/cdp/status.js +38 -0
- package/dist/commands/cdp/theme.js +21 -0
- package/dist/commands/cdp.js +53 -0
- package/dist/commands/clean.js +34 -0
- package/dist/commands/deploy.js +75 -0
- package/dist/commands/finalize-release.js +238 -0
- package/dist/commands/install.js +37 -0
- package/dist/commands/launch.js +150 -0
- package/dist/commands/lib/dependencies.js +35 -0
- package/dist/commands/lib/deploy-precheck.js +117 -0
- package/dist/commands/lib/ensure-target.js +300 -0
- package/dist/commands/logs.js +185 -0
- package/dist/commands/package.js +31 -0
- package/dist/commands/publish.js +34 -0
- package/dist/commands/push-secrets.js +141 -0
- package/dist/commands/release.js +286 -0
- package/dist/commands/runner.js +1874 -0
- package/dist/commands/sign-windows.js +563 -0
- package/dist/commands/test.js +121 -0
- package/dist/commands/update.js +21 -0
- package/dist/commands/validate-certs.js +238 -0
- package/dist/commands/version.js +9 -0
- package/dist/config/page-template.html +35 -0
- package/dist/defaults/.github/workflows/build.yml +276 -0
- package/dist/defaults/AGENTS.md +109 -0
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +1 -0
- package/dist/defaults/_.gitignore +24 -0
- package/dist/defaults/_mas/README.md +49 -0
- package/dist/defaults/_mas/entitlements.mas.inherit.plist +12 -0
- package/dist/defaults/_mas/entitlements.mas.loginhelper.plist +8 -0
- package/dist/defaults/_mas/entitlements.mas.plist +33 -0
- package/dist/defaults/config/certs/.gitkeep +0 -0
- package/dist/defaults/config/certs/README.md +60 -0
- package/dist/defaults/config/icons/macos/dmg.png +0 -0
- package/dist/defaults/config/icons/macos/icon.png +0 -0
- package/dist/defaults/config/icons/macos/tray.png +0 -0
- package/dist/defaults/config/icons/windows/icon.png +0 -0
- package/dist/defaults/config/omega.json5 +279 -0
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/gulpfile.js +6 -0
- package/dist/defaults/hooks/build/post.js +9 -0
- package/dist/defaults/hooks/build/pre.js +9 -0
- package/dist/defaults/hooks/notarize/post.js +16 -0
- package/dist/defaults/hooks/release/post.js +9 -0
- package/dist/defaults/hooks/release/pre.js +9 -0
- package/dist/defaults/src/assets/js/components/about/index.js +10 -0
- package/dist/defaults/src/assets/js/components/main/index.js +14 -0
- package/dist/defaults/src/assets/js/components/settings/index.js +10 -0
- package/dist/defaults/src/assets/scss/main.scss +34 -0
- package/dist/defaults/src/assets/scss/pages/about.scss +3 -0
- package/dist/defaults/src/assets/scss/pages/main.scss +4 -0
- package/dist/defaults/src/assets/scss/pages/settings.scss +3 -0
- package/dist/defaults/src/integrations/context-menu/index.js +60 -0
- package/dist/defaults/src/integrations/menu/index.js +58 -0
- package/dist/defaults/src/integrations/tray/index.js +60 -0
- package/dist/defaults/src/main.js +78 -0
- package/dist/defaults/src/preload.js +15 -0
- package/dist/defaults/src/views/about/index.html +3 -0
- package/dist/defaults/src/views/main/index.html +8 -0
- package/dist/defaults/src/views/settings/index.html +3 -0
- package/dist/defaults/test/README.md +41 -0
- package/dist/defaults/test/_init.js +10 -0
- package/dist/gulp/main.js +144 -0
- package/dist/gulp/tasks/audit.js +82 -0
- package/dist/gulp/tasks/build-config.js +445 -0
- package/dist/gulp/tasks/bundle.js +451 -0
- package/dist/gulp/tasks/defaults.js +20 -0
- package/dist/gulp/tasks/distribute.js +8 -0
- package/dist/gulp/tasks/html.js +95 -0
- package/dist/gulp/tasks/package-quick.js +102 -0
- package/dist/gulp/tasks/package.js +53 -0
- package/dist/gulp/tasks/release.js +57 -0
- package/dist/gulp/tasks/sass.js +82 -0
- package/dist/gulp/tasks/serve.js +191 -0
- package/dist/hooks/notarize.js +70 -0
- package/dist/index.js +14 -0
- package/dist/lib/_menu-mixin.js +199 -0
- package/dist/lib/analytics.js +360 -0
- package/dist/lib/app-state.js +220 -0
- package/dist/lib/auth-flow.js +160 -0
- package/dist/lib/auth-persistence.js +207 -0
- package/dist/lib/auto-updater.js +752 -0
- package/dist/lib/client-bridge.js +371 -0
- package/dist/lib/context-menu.js +302 -0
- package/dist/lib/context.js +162 -0
- package/dist/lib/deep-link.js +370 -0
- package/dist/lib/fontawesome.js +203 -0
- package/dist/lib/ipc.js +169 -0
- package/dist/lib/logger-lite.js +259 -0
- package/dist/lib/logger.js +4 -0
- package/dist/lib/menu.js +521 -0
- package/dist/lib/protocol.js +85 -0
- package/dist/lib/remote-config.js +224 -0
- package/dist/lib/remote-scripts.js +158 -0
- package/dist/lib/restart-manager/index.js +550 -0
- package/dist/lib/restart-manager/install.js +353 -0
- package/dist/lib/restart-manager/protocol.js +274 -0
- package/dist/lib/sign-helpers/auto-unlock.js +95 -0
- package/dist/lib/sign-helpers/entitlements.js +98 -0
- package/dist/lib/sign-helpers/resolve-icons.js +171 -0
- package/dist/lib/sign-helpers/sign-events.js +75 -0
- package/dist/lib/sign-helpers/update-info.js +186 -0
- package/dist/lib/startup.js +214 -0
- package/dist/lib/storage.js +193 -0
- package/dist/lib/templating.js +85 -0
- package/dist/lib/theme.js +173 -0
- package/dist/lib/tray.js +414 -0
- package/dist/lib/usage.js +141 -0
- package/dist/lib/window-manager.js +509 -0
- package/dist/main.js +542 -0
- package/dist/omega-bin.js +6 -0
- package/dist/preload.js +241 -0
- package/dist/renderer.js +456 -0
- package/dist/test/assert.js +4 -0
- package/dist/test/fixtures/consumer-app/config/omega.json5 +39 -0
- package/dist/test/fixtures/consumer-app/package.json +13 -0
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +11 -0
- package/dist/test/fixtures/consumer-app/src/assets/scss/main.scss +3 -0
- package/dist/test/fixtures/consumer-app/src/main.js +17 -0
- package/dist/test/fixtures/consumer-app/src/preload.js +4 -0
- package/dist/test/fixtures/consumer-app/src/views/main/index.html +4 -0
- package/dist/test/harness/boot-entry.js +237 -0
- package/dist/test/harness/main-entry.js +494 -0
- package/dist/test/harness/package.json +6 -0
- package/dist/test/harness/renderer-entry.js +173 -0
- package/dist/test/harness/renderer-preload.js +310 -0
- package/dist/test/harness/renderer.html +12 -0
- package/dist/test/index.js +65 -0
- package/dist/test/runner.js +99 -0
- package/dist/test/runners/boot.js +414 -0
- package/dist/test/runners/electron.js +92 -0
- package/dist/test/runners/render-event.js +46 -0
- package/dist/test/suites/boot/build-isolation.test.js +54 -0
- package/dist/test/suites/boot/consumer-app-boots.test.js +99 -0
- package/dist/test/suites/boot/restart-manager.test.js +38 -0
- package/dist/test/suites/boot/storage-bundled.test.js +59 -0
- package/dist/test/suites/boot/theme.test.js +68 -0
- package/dist/test/suites/boot/view-suite.test.js +47 -0
- package/dist/test/suites/build/attach-log-file.test.js +99 -0
- package/dist/test/suites/build/audit.test.js +271 -0
- package/dist/test/suites/build/boot-fixture.test.js +48 -0
- package/dist/test/suites/build/build-config.test.js +457 -0
- package/dist/test/suites/build/build-verbs.test.js +156 -0
- package/dist/test/suites/build/build-workflow-jobs.test.js +55 -0
- package/dist/test/suites/build/cdp.test.js +89 -0
- package/dist/test/suites/build/cli.test.js +135 -0
- package/dist/test/suites/build/config-schema.test.js +133 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +192 -0
- package/dist/test/suites/build/deliver-certs.test.js +95 -0
- package/dist/test/suites/build/derive-signing-env.test.js +122 -0
- package/dist/test/suites/build/electron-node-version.test.js +49 -0
- package/dist/test/suites/build/electron-targets.test.js +92 -0
- package/dist/test/suites/build/ensure-target.test.js +131 -0
- package/dist/test/suites/build/entitlements.test.js +107 -0
- package/dist/test/suites/build/env-delivery.test.js +166 -0
- package/dist/test/suites/build/env-watch.test.js +86 -0
- package/dist/test/suites/build/exports.test.js +63 -0
- package/dist/test/suites/build/finalize-release.test.js +152 -0
- package/dist/test/suites/build/format-fetch-error.test.js +85 -0
- package/dist/test/suites/build/framework-deps.test.js +173 -0
- package/dist/test/suites/build/get-config.test.js +137 -0
- package/dist/test/suites/build/github-utils.test.js +54 -0
- package/dist/test/suites/build/icon-sheet.test.js +62 -0
- package/dist/test/suites/build/license-stamp.test.js +63 -0
- package/dist/test/suites/build/logger-lite.test.js +148 -0
- package/dist/test/suites/build/logs-command.test.js +226 -0
- package/dist/test/suites/build/manager.test.js +193 -0
- package/dist/test/suites/build/menu-mixin.test.js +130 -0
- package/dist/test/suites/build/merge-line-files.test.js +230 -0
- package/dist/test/suites/build/omega-shell.test.js +94 -0
- package/dist/test/suites/build/omega-tokens.test.js +64 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +90 -0
- package/dist/test/suites/build/push-secrets.test.js +226 -0
- package/dist/test/suites/build/release-pipeline.test.js +365 -0
- package/dist/test/suites/build/renderer-auth-bridge.test.js +158 -0
- package/dist/test/suites/build/renderer-entry-key.test.js +37 -0
- package/dist/test/suites/build/renderer-node-shims.test.js +125 -0
- package/dist/test/suites/build/resolve-icons.test.js +296 -0
- package/dist/test/suites/build/resolve-signing-cert.test.js +342 -0
- package/dist/test/suites/build/restart-manager-install.test.js +178 -0
- package/dist/test/suites/build/restart-manager-protocol.test.js +158 -0
- package/dist/test/suites/build/run-consumer-hook.test.js +137 -0
- package/dist/test/suites/build/runner.test.js +2599 -0
- package/dist/test/suites/build/sanitize-signing-env.test.js +98 -0
- package/dist/test/suites/build/sanitize-url.test.js +78 -0
- package/dist/test/suites/build/secure-remote-url.test.js +42 -0
- package/dist/test/suites/build/sentry.test.js +89 -0
- package/dist/test/suites/build/serve-resolve-electron.test.js +58 -0
- package/dist/test/suites/build/setup-scripts.test.js +172 -0
- package/dist/test/suites/build/sign-events.test.js +90 -0
- package/dist/test/suites/build/sign-windows-e2e.test.js +302 -0
- package/dist/test/suites/build/sign-windows.test.js +313 -0
- package/dist/test/suites/build/strip-dev-blocks.test.js +116 -0
- package/dist/test/suites/build/templating.test.js +95 -0
- package/dist/test/suites/build/test-discovery.test.js +64 -0
- package/dist/test/suites/build/test-stealth.test.js +83 -0
- package/dist/test/suites/build/test-target-no-match.test.js +119 -0
- package/dist/test/suites/build/update-info.test.js +224 -0
- package/dist/test/suites/build/url-helpers.test.js +289 -0
- package/dist/test/suites/build/validate-certs.test.js +103 -0
- package/dist/test/suites/build/validate-config.test.js +90 -0
- package/dist/test/suites/build/verb-logs.test.js +43 -0
- package/dist/test/suites/build/wave5-pins.test.js +35 -0
- package/dist/test/suites/main/analytics.test.js +364 -0
- package/dist/test/suites/main/app-state.test.js +197 -0
- package/dist/test/suites/main/auth-flow.test.js +196 -0
- package/dist/test/suites/main/auth-persistence.test.js +167 -0
- package/dist/test/suites/main/auto-updater.test.js +1138 -0
- package/dist/test/suites/main/boot-sequence.test.js +77 -0
- package/dist/test/suites/main/client-bridge.integration.test.js +134 -0
- package/dist/test/suites/main/client-bridge.test.js +249 -0
- package/dist/test/suites/main/context-menu.test.js +365 -0
- package/dist/test/suites/main/context.test.js +155 -0
- package/dist/test/suites/main/deep-link.test.js +288 -0
- package/dist/test/suites/main/epipe-handler.test.js +40 -0
- package/dist/test/suites/main/fontawesome.test.js +147 -0
- package/dist/test/suites/main/harness-cdp.test.js +49 -0
- package/dist/test/suites/main/ipc.test.js +165 -0
- package/dist/test/suites/main/menu.test.js +419 -0
- package/dist/test/suites/main/protocol.test.js +77 -0
- package/dist/test/suites/main/remote-config.test.js +189 -0
- package/dist/test/suites/main/remote-scripts.test.js +276 -0
- package/dist/test/suites/main/restart-manager.test.js +328 -0
- package/dist/test/suites/main/startup-paths-and-ua.test.js +99 -0
- package/dist/test/suites/main/startup.test.js +129 -0
- package/dist/test/suites/main/stealth-window.test.js +74 -0
- package/dist/test/suites/main/storage.test.js +89 -0
- package/dist/test/suites/main/theme.test.js +137 -0
- package/dist/test/suites/main/tray.test.js +322 -0
- package/dist/test/suites/main/truncate-on-boot.test.js +22 -0
- package/dist/test/suites/main/url-helpers.test.js +429 -0
- package/dist/test/suites/main/usage.test.js +127 -0
- package/dist/test/suites/main/window-bounds.test.js +169 -0
- package/dist/test/suites/main/window-manager.test.js +233 -0
- package/dist/test/suites/renderer/analytics-bridge.test.js +128 -0
- package/dist/test/suites/renderer/cross-context-helpers.test.js +131 -0
- package/dist/test/suites/renderer/fontawesome.test.js +190 -0
- package/dist/test/suites/renderer/round-trip.test.js +107 -0
- package/dist/test/suites/renderer/theme.test.js +118 -0
- package/dist/test/suites/renderer/tooltips.test.js +166 -0
- package/dist/test/suites/renderer/verts.test.js +100 -0
- package/dist/test/suites/renderer/window-em-surface.test.js +107 -0
- package/dist/test/utils/dist-snapshot.js +36 -0
- package/dist/test/utils/extended-mode-warning.js +13 -0
- package/dist/utils/app-root.js +28 -0
- package/dist/utils/attach-log-file.js +4 -0
- package/dist/utils/build-pipeline.js +58 -0
- package/dist/utils/deliver-certs.js +69 -0
- package/dist/utils/derive-signing-env.js +56 -0
- package/dist/utils/dist-root.js +21 -0
- package/dist/utils/electron-node-version.js +48 -0
- package/dist/utils/electron-targets.js +72 -0
- package/dist/utils/format-fetch-error.js +38 -0
- package/dist/utils/github.js +73 -0
- package/dist/utils/load-consumer-file.js +26 -0
- package/dist/utils/merge-line-files.js +5 -0
- package/dist/utils/mode-helpers.js +147 -0
- package/dist/utils/resolve-signing-cert.js +175 -0
- package/dist/utils/run-consumer-hook.js +38 -0
- package/dist/utils/runner-env.js +687 -0
- package/dist/utils/safe-install.js +4 -0
- package/dist/utils/sanitize-signing-env.js +45 -0
- package/dist/utils/sanitize-url.js +28 -0
- package/dist/utils/secure-remote-url.js +25 -0
- package/dist/utils/stealth-window.js +37 -0
- package/dist/utils/test-stealth.js +29 -0
- package/dist/utils/url-helpers.js +169 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/analytics/adapters/ga4.js +26 -0
- package/dist/vendor/analytics/adapters/meta.js +26 -0
- package/dist/vendor/analytics/adapters/resolve.js +130 -0
- package/dist/vendor/analytics/adapters/tiktok.js +27 -0
- package/dist/vendor/analytics/catalog.js +908 -0
- package/dist/vendor/analytics/consent.js +49 -0
- package/dist/vendor/analytics/core.js +141 -0
- package/dist/vendor/analytics/identity.js +136 -0
- package/dist/vendor/analytics/index.js +170 -0
- package/dist/vendor/analytics/logger.js +40 -0
- package/dist/vendor/analytics/transports/browser.js +110 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/actions-secrets.js +145 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bundle.js +292 -0
- package/dist/vendor/devkit/certs.js +199 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/clean-dirs.js +28 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-precheck.js +54 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/empty-modules-plugin.js +64 -0
- package/dist/vendor/devkit/env-watch.js +132 -0
- package/dist/vendor/devkit/framework-deps.js +46 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/npm-registry.js +52 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/prompt.js +187 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
- package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
- package/dist/vendor/devkit/target-dependencies.js +137 -0
- package/dist/vendor/devkit/target-secrets.js +165 -0
- package/dist/vendor/devkit/test/assert.js +120 -0
- package/dist/vendor/devkit/test/define-cases.js +104 -0
- package/dist/vendor/devkit/test/extended-mode-warning.js +22 -0
- package/dist/vendor/devkit/test/runner-core.js +554 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/monitoring/core.js +180 -0
- package/dist/vendor/monitoring/env.js +49 -0
- package/dist/vendor/monitoring/index.js +28 -0
- package/dist/vendor/monitoring/logger.js +39 -0
- package/dist/vendor/monitoring/main.js +99 -0
- package/dist/vendor/monitoring/preload.js +45 -0
- package/dist/vendor/monitoring/renderer.js +87 -0
- package/docs/analytics.md +140 -0
- package/docs/app-state.md +92 -0
- package/docs/audit.md +69 -0
- package/docs/auto-updater.md +243 -0
- package/docs/boot-sequence.md +39 -0
- package/docs/build-system.md +161 -0
- package/docs/cdp-debugging.md +169 -0
- package/docs/client-bridge.md +267 -0
- package/docs/common-mistakes.md +21 -0
- package/docs/config-schema.md +120 -0
- package/docs/context-menu.md +112 -0
- package/docs/context.md +81 -0
- package/docs/css.md +84 -0
- package/docs/deep-link.md +178 -0
- package/docs/environment-detection.md +104 -0
- package/docs/fontawesome.md +107 -0
- package/docs/hooks.md +87 -0
- package/docs/icons.md +79 -0
- package/docs/index.md +279 -0
- package/docs/installer-options.md +162 -0
- package/docs/ipc.md +61 -0
- package/docs/lib-modules.md +53 -0
- package/docs/logging.md +229 -0
- package/docs/menu.md +160 -0
- package/docs/releasing.md +229 -0
- package/docs/remote-config.md +118 -0
- package/docs/remote-scripts.md +144 -0
- package/docs/restart-manager.md +144 -0
- package/docs/runner.md +253 -0
- package/docs/sentry.md +97 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/signing.md +267 -0
- package/docs/startup.md +142 -0
- package/docs/storage.md +59 -0
- package/docs/templating.md +101 -0
- package/docs/test-boot-layer.md +157 -0
- package/docs/test-framework.md +357 -0
- package/docs/themes.md +135 -0
- package/docs/tooltips.md +99 -0
- package/docs/tray.md +164 -0
- package/docs/usage.md +58 -0
- package/docs/verts.md +62 -0
- package/docs/windows.md +149 -0
- package/package.json +184 -0
- package/scripts/sync-nvmrc.js +100 -0
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
// Strategy-aware Windows code signer.
|
|
2
|
+
//
|
|
3
|
+
// Reads strategy from config platforms.win.signing.strategy:
|
|
4
|
+
// self-hosted — sign with signtool against an EV USB token (typically on a self-hosted runner)
|
|
5
|
+
// cloud — shell out to a cloud signing provider's CLI (Azure / SSL.com / DigiCert)
|
|
6
|
+
// local — no-op (developer signs manually on their own Windows box)
|
|
7
|
+
//
|
|
8
|
+
// Usage:
|
|
9
|
+
// npx omega sign-windows # sign every .exe/.msi under ./release
|
|
10
|
+
// npx omega sign-windows --in release/ --out release/signed/
|
|
11
|
+
// npx omega sign-windows --verify-only # don't sign, just verify existing signatures
|
|
12
|
+
// npx omega sign-windows --smoke # sign a 1-byte dummy .exe to validate the setup
|
|
13
|
+
// npx omega sign-windows --target some-binary.exe # sign a single specific file
|
|
14
|
+
//
|
|
15
|
+
// Cloud provider modules will live in src/lib/sign-providers/{azure,sslcom,digicert}.js
|
|
16
|
+
// (Pass 3 work). For now the cloud branch logs the intended provider command and exits cleanly.
|
|
17
|
+
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const jetpack = require('fs-jetpack');
|
|
22
|
+
const { execute } = require('node-powertools');
|
|
23
|
+
|
|
24
|
+
const Manager = new (require('../build.js'));
|
|
25
|
+
const logger = Manager.logger('sign-windows');
|
|
26
|
+
|
|
27
|
+
// The box's own signing configuration (`<runner home>\.env`: the cert, the PIN,
|
|
28
|
+
// signtool) is read before anything below looks at process.env, so a manual
|
|
29
|
+
// sign, `--smoke` and the e2e suite work from any directory. A CI-delivered
|
|
30
|
+
// value wins over the file (utils/runner-env.js).
|
|
31
|
+
const runnerEnv = require('../utils/runner-env.js');
|
|
32
|
+
runnerEnv.loadRunnerEnv();
|
|
33
|
+
const attachLogFile = require('../utils/attach-log-file.js');
|
|
34
|
+
|
|
35
|
+
const { startAutoUnlock } = require('../lib/sign-helpers/auto-unlock.js');
|
|
36
|
+
const { writeUpdateInfo } = require('../lib/sign-helpers/update-info.js');
|
|
37
|
+
const signEvents = require('../lib/sign-helpers/sign-events.js');
|
|
38
|
+
|
|
39
|
+
module.exports = async function (options) {
|
|
40
|
+
options = options || {};
|
|
41
|
+
|
|
42
|
+
// The box's own record of what it signed, beside the install — the same file
|
|
43
|
+
// `omega runner` writes, since a sign is one of the things the box did. Its
|
|
44
|
+
// OWN tee, so an outer verb's log file survives this one's detach.
|
|
45
|
+
//
|
|
46
|
+
// `attachInCI` because this file is the BOX's, not the workspace's: the
|
|
47
|
+
// `windows-sign` job IS the run whose trail the box needs to keep. `append`
|
|
48
|
+
// because the `runner start` listener that spawned this holds the same file.
|
|
49
|
+
const logTarget = boxLogTarget();
|
|
50
|
+
const tee = attachLogFile.createTee();
|
|
51
|
+
if (logTarget) tee.attach(logTarget, { attachInCI: true, append: true });
|
|
52
|
+
|
|
53
|
+
const jobStart = Date.now();
|
|
54
|
+
// GITHUB_REPOSITORY is "<owner>/<repo>" inside a GH Actions runner — split for the
|
|
55
|
+
// monitor banner. GITHUB_REPOSITORY_OWNER is the same thing as the owner half but is
|
|
56
|
+
// sometimes the better source on org-vs-user runs. Both are provided automatically by
|
|
57
|
+
// actions/runner; only present when invoked from a workflow job.
|
|
58
|
+
const repoFull = process.env.GITHUB_REPOSITORY || '';
|
|
59
|
+
const [ghOwner, ghRepo] = repoFull.includes('/') ? repoFull.split('/') : [process.env.GITHUB_REPOSITORY_OWNER || null, null];
|
|
60
|
+
signEvents.emit('job-start', {
|
|
61
|
+
options: Object.fromEntries(Object.entries(options).filter(([k]) => k !== '_')),
|
|
62
|
+
runner_workspace: process.env.RUNNER_WORKSPACE || null,
|
|
63
|
+
github_run_id: process.env.GITHUB_RUN_ID || null,
|
|
64
|
+
github_workflow: process.env.GITHUB_WORKFLOW || null,
|
|
65
|
+
github_owner: ghOwner || null,
|
|
66
|
+
github_repo: ghRepo || null,
|
|
67
|
+
});
|
|
68
|
+
logger.log(`Signing event log: ${signEvents.getLogPath()}`);
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const result = await runSignCommand(options);
|
|
72
|
+
signEvents.emit('job-end', { ok: true, duration_ms: Date.now() - jobStart });
|
|
73
|
+
return result;
|
|
74
|
+
} catch (e) {
|
|
75
|
+
signEvents.emit('job-end', { ok: false, duration_ms: Date.now() - jobStart, error: e?.message || String(e) });
|
|
76
|
+
throw e;
|
|
77
|
+
} finally {
|
|
78
|
+
tee.detach();
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
async function runSignCommand(options) {
|
|
83
|
+
// Smoke test mode: create a 1-byte .exe in a temp dir, sign it, verify it, clean up.
|
|
84
|
+
// This is the fastest possible end-to-end check that the EV token, drivers, signtool,
|
|
85
|
+
// and password cache are all working — no @omega.js/desktop build required.
|
|
86
|
+
if (options.smoke) {
|
|
87
|
+
await runnerEnv.ensureRunnerConfig({ logger, scopes: ['signing'] });
|
|
88
|
+
return smokeTest();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const strategy = Manager.getWindowsSignStrategy();
|
|
92
|
+
|
|
93
|
+
const config = Manager.getConfig();
|
|
94
|
+
const projectRoot = process.cwd();
|
|
95
|
+
|
|
96
|
+
// Resolve --in and --out (CLI flags) → directories of unsigned / signed artifacts.
|
|
97
|
+
const inDir = options.in ? path.resolve(projectRoot, options.in) : path.join(projectRoot, 'release');
|
|
98
|
+
const outDir = options.out ? path.resolve(projectRoot, options.out) : path.join(projectRoot, 'release', 'signed');
|
|
99
|
+
|
|
100
|
+
// Single-target shortcut — useful for debugging a specific failure.
|
|
101
|
+
let targets;
|
|
102
|
+
if (options.target) {
|
|
103
|
+
const t = path.resolve(projectRoot, options.target);
|
|
104
|
+
if (!jetpack.exists(t)) throw new Error(`--target file does not exist: ${t}`);
|
|
105
|
+
targets = [t];
|
|
106
|
+
} else {
|
|
107
|
+
if (!jetpack.exists(inDir)) {
|
|
108
|
+
throw new Error(`Input directory does not exist: ${inDir}`);
|
|
109
|
+
}
|
|
110
|
+
targets = jetpack.find(inDir, { matching: ['*.exe', '*.msi'], recursive: true, files: true, directories: false });
|
|
111
|
+
if (targets.length === 0) {
|
|
112
|
+
logger.warn(`No .exe / .msi files found under ${inDir} — nothing to sign.`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Signing HERE needs the box's cert, PIN and signtool: ask for what is missing
|
|
118
|
+
// in a terminal, refuse without one. The cloud strategy has no such needs.
|
|
119
|
+
// After the input checks on purpose: a mistyped --target fails before anyone
|
|
120
|
+
// is asked for a PIN.
|
|
121
|
+
if (strategy === 'self-hosted' || strategy === 'local') {
|
|
122
|
+
await runnerEnv.ensureRunnerConfig({ logger, scopes: ['signing'] });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Verify-only mode: don't sign anything, just run signtool verify against each.
|
|
126
|
+
if (options['verify-only'] || options.verifyOnly) {
|
|
127
|
+
return verifyOnly(targets);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
jetpack.dir(outDir);
|
|
131
|
+
|
|
132
|
+
logger.log(`Signing ${targets.length} artifact(s) — strategy=${strategy}, in=${path.relative(projectRoot, inDir)}, out=${path.relative(projectRoot, outDir)}`);
|
|
133
|
+
|
|
134
|
+
if (strategy === 'self-hosted' || strategy === 'local') {
|
|
135
|
+
if (strategy === 'local') {
|
|
136
|
+
logger.warn('strategy=local — this command will run signtool against whatever cert config the local box has. Make sure your EV token is plugged in.');
|
|
137
|
+
}
|
|
138
|
+
await signWithSigntool(targets, inDir, outDir);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (strategy === 'cloud') {
|
|
143
|
+
const provider = config.platforms?.win?.signing?.cloud?.provider;
|
|
144
|
+
if (!provider) {
|
|
145
|
+
throw new Error('strategy=cloud but no provider set (config platforms.win.signing.cloud.provider).');
|
|
146
|
+
}
|
|
147
|
+
await signWithCloudProvider(provider, targets, inDir, outDir);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
throw new Error(`Unknown Windows signing strategy: ${strategy}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// The runner log this run may tee to, or null.
|
|
155
|
+
//
|
|
156
|
+
// Off Windows there is no box home at all, so a manual mac/linux sign drops no
|
|
157
|
+
// `.gh-runners/` into the cwd. And from a TEST run the box's own record is off
|
|
158
|
+
// limits unless the home is a scratch one — a suite pointed at a real home
|
|
159
|
+
// writes nothing rather than overwriting what the box did
|
|
160
|
+
// ([#337](https://github.com/Omega-JS-Stack/omega/issues/337)).
|
|
161
|
+
//
|
|
162
|
+
// `env` and `platform` resolve the HOME (the test seam); whether this is a test
|
|
163
|
+
// run is read from process.env by isTestRun, always — never from an argument.
|
|
164
|
+
//
|
|
165
|
+
// @param {object} [env] - Environment the home is resolved from.
|
|
166
|
+
// @param {string} [platform] - Platform the default home is resolved for.
|
|
167
|
+
// @returns {string|null}
|
|
168
|
+
function boxLogTarget(env, platform) {
|
|
169
|
+
env = env || process.env;
|
|
170
|
+
platform = platform || process.platform;
|
|
171
|
+
|
|
172
|
+
const home = env.OMEGA_RUNNER_HOME
|
|
173
|
+
|| (platform === 'win32' ? runnerEnv.defaultRunnerHome(platform, env) : null);
|
|
174
|
+
if (!home) return null;
|
|
175
|
+
if (runnerEnv.isTestRun() && !runnerEnv.isScratchRunnerHome(home)) return null;
|
|
176
|
+
|
|
177
|
+
return runnerEnv.runnerLogFile(home);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// signtool path (Windows SDK). Falls back to plain `signtool` on PATH.
|
|
181
|
+
function getSigntoolPath(env) {
|
|
182
|
+
env = env || process.env;
|
|
183
|
+
if (env.SIGNTOOL_PATH) return env.SIGNTOOL_PATH;
|
|
184
|
+
return 'signtool'; // assume on PATH; SDK installers add it
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Detect whether WIN_EV_TOKEN_PATH is a SHA1 thumbprint (40 hex chars, optional spaces)
|
|
188
|
+
// vs. a file path. SafeNet/eToken-managed certs live in the user store and are selected
|
|
189
|
+
// by thumbprint via /sha1; .pfx files are passed via /f + /p.
|
|
190
|
+
function isThumbprint(value) {
|
|
191
|
+
if (!value) return false;
|
|
192
|
+
const stripped = value.replace(/\s+/g, '');
|
|
193
|
+
return /^[0-9a-fA-F]{40}$/.test(stripped);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Every signtool input, resolved from the environment in one place, with the
|
|
197
|
+
// loud named error when a required one is missing.
|
|
198
|
+
//
|
|
199
|
+
// WIN_EV_TOKEN_PATH is the ONE name for the certificate reference — the schema
|
|
200
|
+
// name ([#337](https://github.com/Omega-JS-Stack/omega/issues/337)). The old
|
|
201
|
+
// WIN_CSC_LINK alias is gone: two names for one key means two things to keep
|
|
202
|
+
// straight on a box nobody logs into.
|
|
203
|
+
function resolveSigntoolEnv(env) {
|
|
204
|
+
env = env || process.env;
|
|
205
|
+
|
|
206
|
+
const tokenRef = env.WIN_EV_TOKEN_PATH;
|
|
207
|
+
if (!tokenRef) {
|
|
208
|
+
throw new Error('WIN_EV_TOKEN_PATH not set — cannot sign. Set it to the EV cert SHA1 thumbprint (SafeNet/eToken) or a .pfx path.');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const password = env.WIN_CSC_KEY_PASSWORD;
|
|
212
|
+
const useThumbprint = isThumbprint(tokenRef);
|
|
213
|
+
|
|
214
|
+
// Thumbprint mode (SafeNet/eToken): signtool finds cert in user store, SafeNet handles auth.
|
|
215
|
+
// File mode (.pfx): /f + /p, password handed to signtool directly.
|
|
216
|
+
if (!useThumbprint && !password) {
|
|
217
|
+
throw new Error('WIN_CSC_KEY_PASSWORD not set — required when WIN_EV_TOKEN_PATH is a .pfx path.');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
tokenRef,
|
|
222
|
+
password,
|
|
223
|
+
useThumbprint,
|
|
224
|
+
signtool: getSigntoolPath(env),
|
|
225
|
+
timestampUrl: env.WIN_TIMESTAMP_URL || 'http://timestamp.sectigo.com',
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// The `signtool sign` command line, as one string. Pure, so the exact argument
|
|
230
|
+
// order for both cert modes is provable without a Windows box.
|
|
231
|
+
//
|
|
232
|
+
// It ends in `2>&1` because signtool writes its diagnosis to stderr and the
|
|
233
|
+
// retry classifier below reads `e.message` — without the redirect a wrong PIN
|
|
234
|
+
// can arrive as a bare exit code and get retried three times.
|
|
235
|
+
function buildSignCommand({ signtool, tokenRef, password, timestampUrl, outPath }) {
|
|
236
|
+
const certArgs = isThumbprint(tokenRef)
|
|
237
|
+
? [`/sha1 ${tokenRef.replace(/\s+/g, '')}`]
|
|
238
|
+
: [`/f "${tokenRef}"`, `/p "${password}"`];
|
|
239
|
+
|
|
240
|
+
return [
|
|
241
|
+
`"${signtool}"`,
|
|
242
|
+
'sign',
|
|
243
|
+
...certArgs,
|
|
244
|
+
`/tr "${timestampUrl}"`,
|
|
245
|
+
'/td sha256',
|
|
246
|
+
'/fd sha256',
|
|
247
|
+
`"${outPath}"`,
|
|
248
|
+
'2>&1',
|
|
249
|
+
].join(' ');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// The `signtool verify` command line. Local-only, so it stays single-shot.
|
|
253
|
+
function buildVerifyCommand({ signtool, outPath }) {
|
|
254
|
+
return `"${signtool}" verify /pa "${outPath}"`;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// The sign call reaches a THIRD PARTY — the timestamp server — and that is the
|
|
258
|
+
// one part of signing that fails and then works seconds later (rate limit, 502,
|
|
259
|
+
// a dropped connection mid-handshake). So the sign call gets three attempts with
|
|
260
|
+
// a short backoff; verify is local and never retries.
|
|
261
|
+
const SIGN_ATTEMPTS = 3;
|
|
262
|
+
const SIGN_RETRY_DELAY_MS = 5000;
|
|
263
|
+
|
|
264
|
+
// node-powertools' `execute` with `log: false` — what this file passes — rejects
|
|
265
|
+
// with `new Error(stderr || 'Command failed with exit code N')`, and the sign
|
|
266
|
+
// command ends in `2>&1` (it runs through a shell), so BOTH of signtool's
|
|
267
|
+
// streams reach `e.message` and this is classifying on signtool's own words.
|
|
268
|
+
//
|
|
269
|
+
// Failures signtool NAMES as permanent. Retrying a wrong PIN walks the EV token
|
|
270
|
+
// toward a lockout, and no amount of waiting conjures a certificate that isn't
|
|
271
|
+
// in the store — so these stop on the first attempt. Anything else (including a
|
|
272
|
+
// bare exit code, where signtool told us nothing) is treated as transient and
|
|
273
|
+
// retried, because a lost timestamp round-trip looks exactly like that.
|
|
274
|
+
const NON_TRANSIENT_SIGN_FAILURES = [
|
|
275
|
+
/No certificates were found/i,
|
|
276
|
+
/password is not correct/i,
|
|
277
|
+
/token .{0,20}locked/i,
|
|
278
|
+
/hash on the file is malformed/i,
|
|
279
|
+
];
|
|
280
|
+
|
|
281
|
+
function isTransientSignFailure(error) {
|
|
282
|
+
const message = String(error?.message || error || '');
|
|
283
|
+
return !NON_TRANSIENT_SIGN_FAILURES.some((re) => re.test(message));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Run `cmd` with the retry policy above. Every attempt lands in the signing
|
|
287
|
+
// event log, so `runner monitor` shows the retries as they happen. Throws the
|
|
288
|
+
// last error when it gives up.
|
|
289
|
+
//
|
|
290
|
+
// `startUnlock` is called PER ATTEMPT and stopped the moment that attempt ends.
|
|
291
|
+
// SafeNet raises its "Token Logon" dialog on every signtool call, and the
|
|
292
|
+
// watcher returns as soon as it has typed once — so a single watcher wrapped
|
|
293
|
+
// around the whole loop leaves attempts 2 and 3 facing the dialog unattended,
|
|
294
|
+
// which is exactly the retry that was supposed to save the job.
|
|
295
|
+
async function signWithRetry(cmd, options) {
|
|
296
|
+
options = options || {};
|
|
297
|
+
const {
|
|
298
|
+
file,
|
|
299
|
+
attempts = SIGN_ATTEMPTS,
|
|
300
|
+
delayMs = SIGN_RETRY_DELAY_MS,
|
|
301
|
+
exec = (c) => execute(c, { log: false }),
|
|
302
|
+
sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
303
|
+
emit = signEvents.emit,
|
|
304
|
+
startUnlock = () => ({ stop: () => {} }),
|
|
305
|
+
} = options;
|
|
306
|
+
|
|
307
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
308
|
+
emit('sign-attempt', { file, attempt, of: attempts });
|
|
309
|
+
|
|
310
|
+
const unlock = startUnlock();
|
|
311
|
+
let failure;
|
|
312
|
+
try {
|
|
313
|
+
return await exec(cmd);
|
|
314
|
+
} catch (e) {
|
|
315
|
+
failure = e;
|
|
316
|
+
} finally {
|
|
317
|
+
// Stopped before the verdict and the backoff — nothing polls the desktop
|
|
318
|
+
// while we are only waiting.
|
|
319
|
+
unlock.stop();
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (attempt === attempts || !isTransientSignFailure(failure)) throw failure;
|
|
323
|
+
emit('sign-retry', {
|
|
324
|
+
file,
|
|
325
|
+
attempt,
|
|
326
|
+
of: attempts,
|
|
327
|
+
retry_in_ms: delayMs,
|
|
328
|
+
error: failure?.message || String(failure),
|
|
329
|
+
});
|
|
330
|
+
await sleep(delayMs);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Unreachable: the loop returns on success and throws on the last attempt.
|
|
334
|
+
throw new Error(`signWithRetry exhausted ${attempts} attempts without a verdict`);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
async function signWithSigntool(targets, inDir, outDir) {
|
|
338
|
+
const projectRoot = process.cwd();
|
|
339
|
+
const { tokenRef, password, useThumbprint, signtool, timestampUrl } = resolveSigntoolEnv();
|
|
340
|
+
|
|
341
|
+
// Track which signed installers are NSIS-style .exe so we can write latest.yml
|
|
342
|
+
// for them after the signing loop. .msi targets use Windows Installer's own
|
|
343
|
+
// update mechanism (not electron-updater) and don't need a yml.
|
|
344
|
+
const signedExes = [];
|
|
345
|
+
|
|
346
|
+
for (const target of targets) {
|
|
347
|
+
const rel = path.relative(inDir, target);
|
|
348
|
+
const outPath = path.join(outDir, rel);
|
|
349
|
+
jetpack.dir(path.dirname(outPath));
|
|
350
|
+
|
|
351
|
+
// Copy first, sign in place at the output location (signtool modifies in-place).
|
|
352
|
+
jetpack.copy(target, outPath, { overwrite: true });
|
|
353
|
+
|
|
354
|
+
const cmd = buildSignCommand({ signtool, tokenRef, password, timestampUrl, outPath });
|
|
355
|
+
|
|
356
|
+
logger.log(`Signing ${path.relative(projectRoot, outPath)}${useThumbprint ? ' (thumbprint mode)' : ''}...`);
|
|
357
|
+
|
|
358
|
+
const fileBytes = (() => { try { return fs.statSync(outPath).size; } catch (_) { return null; } })();
|
|
359
|
+
signEvents.emit('sign-start', {
|
|
360
|
+
file: path.basename(outPath),
|
|
361
|
+
out_path: outPath,
|
|
362
|
+
bytes: fileBytes,
|
|
363
|
+
mode: useThumbprint ? 'thumbprint' : 'pfx',
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// In thumbprint mode against a SafeNet/eToken cert, signtool triggers a
|
|
367
|
+
// "Token Logon" dialog. signWithRetry starts one watcher per attempt to type
|
|
368
|
+
// the password into it, and stops each when that attempt ends.
|
|
369
|
+
const fileStart = Date.now();
|
|
370
|
+
try {
|
|
371
|
+
await signWithRetry(cmd, {
|
|
372
|
+
file: path.basename(outPath),
|
|
373
|
+
startUnlock: () => (useThumbprint ? startAutoUnlock({ password, logger }) : { stop: () => {} }),
|
|
374
|
+
});
|
|
375
|
+
} catch (e) {
|
|
376
|
+
signEvents.emit('sign-fail', {
|
|
377
|
+
file: path.basename(outPath),
|
|
378
|
+
duration_ms: Date.now() - fileStart,
|
|
379
|
+
phase: 'signtool',
|
|
380
|
+
error: e?.message || String(e),
|
|
381
|
+
});
|
|
382
|
+
throw e;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Verify is a local check with no third party in it — one shot.
|
|
386
|
+
const verifyCmd = buildVerifyCommand({ signtool, outPath });
|
|
387
|
+
try {
|
|
388
|
+
await execute(verifyCmd, { log: false });
|
|
389
|
+
} catch (e) {
|
|
390
|
+
signEvents.emit('sign-fail', {
|
|
391
|
+
file: path.basename(outPath),
|
|
392
|
+
duration_ms: Date.now() - fileStart,
|
|
393
|
+
phase: 'verify',
|
|
394
|
+
error: e?.message || String(e),
|
|
395
|
+
});
|
|
396
|
+
throw e;
|
|
397
|
+
}
|
|
398
|
+
signEvents.emit('sign-done', {
|
|
399
|
+
file: path.basename(outPath),
|
|
400
|
+
duration_ms: Date.now() - fileStart,
|
|
401
|
+
});
|
|
402
|
+
logger.log(logger.format.green(`✓ Signed: ${path.relative(projectRoot, outPath)}`));
|
|
403
|
+
|
|
404
|
+
if (outPath.toLowerCase().endsWith('.exe')) {
|
|
405
|
+
signedExes.push({ filePath: outPath, urlName: path.basename(outPath) });
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Generate latest.yml + per-exe .blockmap for the signed NSIS installers. Without
|
|
410
|
+
// this, electron-updater on Windows clients has no way to discover the new release
|
|
411
|
+
// (mac/linux equivalents are produced by electron-builder during their publish step,
|
|
412
|
+
// but Windows is split into a post-build sign job so we have to write the yml here).
|
|
413
|
+
if (signedExes.length > 0) {
|
|
414
|
+
const pkg = Manager.getPackage('project') || {};
|
|
415
|
+
const version = pkg.version;
|
|
416
|
+
if (!version) {
|
|
417
|
+
logger.warn('Could not determine version from package.json — skipping latest.yml generation.');
|
|
418
|
+
} else {
|
|
419
|
+
logger.log(`Generating Windows auto-updater feed (latest.yml) for ${signedExes.length} installer(s)...`);
|
|
420
|
+
try {
|
|
421
|
+
await writeUpdateInfo({
|
|
422
|
+
signedExes,
|
|
423
|
+
outDir,
|
|
424
|
+
version,
|
|
425
|
+
logger,
|
|
426
|
+
});
|
|
427
|
+
} catch (e) {
|
|
428
|
+
// Don't fail the whole sign step if yml generation hits something unexpected —
|
|
429
|
+
// the signed exe is still valid + uploadable. But this IS a real problem
|
|
430
|
+
// because auto-updates won't work, so log loudly.
|
|
431
|
+
logger.error(`latest.yml generation failed: ${e.message}`);
|
|
432
|
+
logger.error(' Signed binary is OK but Windows auto-updater will not see this release.');
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Verify-only: run signtool verify /pa against each target, report whether it's signed.
|
|
439
|
+
// Doesn't fail if some are unsigned — reports each.
|
|
440
|
+
async function verifyOnly(targets) {
|
|
441
|
+
const signtool = getSigntoolPath();
|
|
442
|
+
let signed = 0;
|
|
443
|
+
let unsigned = 0;
|
|
444
|
+
let errored = 0;
|
|
445
|
+
|
|
446
|
+
for (const t of targets) {
|
|
447
|
+
try {
|
|
448
|
+
const out = await execute(`"${signtool}" verify /pa /v "${t}"`, { log: false });
|
|
449
|
+
const trimmed = String(out || '').trim();
|
|
450
|
+
// signtool prints things like "Successfully verified" or details about the chain.
|
|
451
|
+
if (/Successfully verified/i.test(trimmed)) {
|
|
452
|
+
logger.log(logger.format.green(`✓ Signed: ${t}`));
|
|
453
|
+
// Pull the subject CN out for visibility.
|
|
454
|
+
const cn = trimmed.match(/Issued to:\s*(.+)/i)?.[1];
|
|
455
|
+
if (cn) logger.log(` Subject: ${cn.trim()}`);
|
|
456
|
+
signed += 1;
|
|
457
|
+
} else {
|
|
458
|
+
logger.warn(`? Unclear verify output for: ${t}`);
|
|
459
|
+
logger.log(trimmed.split('\n').slice(0, 5).join('\n'));
|
|
460
|
+
errored += 1;
|
|
461
|
+
}
|
|
462
|
+
} catch (e) {
|
|
463
|
+
// signtool exits non-zero on unsigned files.
|
|
464
|
+
logger.warn(`✗ Unsigned or invalid: ${t}`);
|
|
465
|
+
const msg = String(e?.message || e).split('\n').slice(0, 3).join(' ');
|
|
466
|
+
logger.log(` ${msg}`);
|
|
467
|
+
unsigned += 1;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
logger.log(`Verify summary: ${signed} signed, ${unsigned} unsigned, ${errored} unclear (of ${targets.length} total).`);
|
|
472
|
+
return { signed, unsigned, errored, total: targets.length };
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// A real PE/COFF .exe to sign when there is no build to sign: %WINDIR%\System32\where.exe
|
|
476
|
+
// (small, always present, and copying it is fine). One home for that choice, so the smoke
|
|
477
|
+
// test and the Windows-gated end-to-end suite sign the same thing.
|
|
478
|
+
function copySampleExe(destPath, env) {
|
|
479
|
+
env = env || process.env;
|
|
480
|
+
|
|
481
|
+
const sourceExe = path.join(env.WINDIR || 'C:\\Windows', 'System32', 'where.exe');
|
|
482
|
+
if (!jetpack.exists(sourceExe)) {
|
|
483
|
+
throw new Error(`Could not find a sample .exe to sign at ${sourceExe}. Pass --target <path> instead.`);
|
|
484
|
+
}
|
|
485
|
+
jetpack.copy(sourceExe, destPath, { overwrite: true });
|
|
486
|
+
|
|
487
|
+
return destPath;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Smoke test: write a 1-byte .exe to %TEMP%, run the full self-hosted signing flow against it.
|
|
491
|
+
// Validates that EV token, SafeNet drivers, signtool, and the password cache are all functional
|
|
492
|
+
// without needing an actual @omega.js/desktop build. Cleans up after itself.
|
|
493
|
+
async function smokeTest() {
|
|
494
|
+
if (process.platform !== 'win32') {
|
|
495
|
+
throw new Error('--smoke is Windows-only (signtool is required).');
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const { tokenRef, useThumbprint } = resolveSigntoolEnv();
|
|
499
|
+
|
|
500
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-smoke-'));
|
|
501
|
+
const target = copySampleExe(path.join(tmp, 'desktop-smoke-test.exe'));
|
|
502
|
+
|
|
503
|
+
logger.log(`Smoke test: signing a temp copy of where.exe at ${target}`);
|
|
504
|
+
logger.log(`Cert ref: ${tokenRef}${useThumbprint ? ' (thumbprint mode — SafeNet handles auth)' : ' (file mode)'}`);
|
|
505
|
+
|
|
506
|
+
try {
|
|
507
|
+
await signWithSigntool([target], path.dirname(target), path.dirname(target));
|
|
508
|
+
logger.log(logger.format.green('✓ Smoke test passed — EV token + signtool + password cache all working.'));
|
|
509
|
+
} catch (e) {
|
|
510
|
+
logger.error(`Smoke test FAILED: ${e.message}`);
|
|
511
|
+
logger.log('Most common causes:');
|
|
512
|
+
logger.log(' • EV token not plugged in or not detected by SafeNet');
|
|
513
|
+
logger.log(' • SafeNet driver not installed');
|
|
514
|
+
logger.log(' • WIN_CSC_KEY_PASSWORD wrong or token locked (check tray icon)');
|
|
515
|
+
logger.log(' • signtool.exe not on PATH (Windows SDK or VS Build Tools required)');
|
|
516
|
+
throw e;
|
|
517
|
+
} finally {
|
|
518
|
+
try { jetpack.remove(tmp); } catch (e) { /* ignore */ }
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
async function signWithCloudProvider(provider, targets, inDir, outDir) {
|
|
523
|
+
// Provider modules live in src/lib/sign-providers/<name>.js. Each exports
|
|
524
|
+
// async function sign({ targets, inDir, outDir, projectRoot, env }) { ... }
|
|
525
|
+
let providerModule;
|
|
526
|
+
try {
|
|
527
|
+
providerModule = require(path.join(__dirname, '..', 'lib', 'sign-providers', `${provider}.js`));
|
|
528
|
+
} catch (e) {
|
|
529
|
+
throw new Error(`Cloud provider "${provider}" is not yet implemented (no src/lib/sign-providers/${provider}.js). Supported: azure, sslcom, digicert.`);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (typeof providerModule.sign !== 'function') {
|
|
533
|
+
throw new Error(`sign-providers/${provider}.js does not export a sign() function.`);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
await providerModule.sign({
|
|
537
|
+
targets,
|
|
538
|
+
inDir,
|
|
539
|
+
outDir,
|
|
540
|
+
projectRoot: process.cwd(),
|
|
541
|
+
env: process.env,
|
|
542
|
+
logger,
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Exports for testing — the pure halves of the signer: what the command line
|
|
547
|
+
// looks like, which env keys feed it, and when a failure is worth retrying.
|
|
548
|
+
module.exports.isThumbprint = isThumbprint;
|
|
549
|
+
module.exports.boxLogTarget = boxLogTarget;
|
|
550
|
+
module.exports.resolveSigntoolEnv = resolveSigntoolEnv;
|
|
551
|
+
module.exports.buildSignCommand = buildSignCommand;
|
|
552
|
+
module.exports.buildVerifyCommand = buildVerifyCommand;
|
|
553
|
+
module.exports.signWithRetry = signWithRetry;
|
|
554
|
+
module.exports.isTransientSignFailure = isTransientSignFailure;
|
|
555
|
+
module.exports.SIGN_ATTEMPTS = SIGN_ATTEMPTS;
|
|
556
|
+
module.exports.SIGN_RETRY_DELAY_MS = SIGN_RETRY_DELAY_MS;
|
|
557
|
+
|
|
558
|
+
// Exports for the Windows-gated end-to-end suite — the halves that shell out to
|
|
559
|
+
// signtool for real. They only run where signtool and the EV token are
|
|
560
|
+
// (suites/build/sign-windows-e2e.test.js gates on exactly that).
|
|
561
|
+
module.exports.signWithSigntool = signWithSigntool;
|
|
562
|
+
module.exports.verifyOnly = verifyOnly;
|
|
563
|
+
module.exports.copySampleExe = copySampleExe;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const Manager = new (require('../build.js'));
|
|
5
|
+
const logger = Manager.logger('test');
|
|
6
|
+
const { run } = require('../test/runner.js');
|
|
7
|
+
const attachLogFile = require('../utils/attach-log-file.js');
|
|
8
|
+
const { EXTENDED_MODE_WARNING } = require('../test/utils/extended-mode-warning.js');
|
|
9
|
+
const { noMatchMessage, noMatchExitCode } = require('../vendor/devkit/test/scope.js');
|
|
10
|
+
const { ensureTarget } = require('./lib/ensure-target.js');
|
|
11
|
+
|
|
12
|
+
module.exports = async function (options) {
|
|
13
|
+
// This process is a TEST RUN, and everything it spawns inherits that. The box's
|
|
14
|
+
// mutating verbs read it and refuse to touch a real runner home
|
|
15
|
+
// ([#337](https://github.com/Omega-JS-Stack/omega/issues/337): a suite once ran
|
|
16
|
+
// a real `runner install` on the signing box). Deliberately NOT the canonical
|
|
17
|
+
// OMEGA_TEST_MODE, which means "the app under test runs in testing mode" and
|
|
18
|
+
// would change what the boot lane's production build compiles.
|
|
19
|
+
process.env.OMEGA_TEST_RUNNER = '1';
|
|
20
|
+
|
|
21
|
+
// Tee all test output to <projectRoot>/logs/test.log (ANSI-stripped) — mirrors
|
|
22
|
+
// @omega.js/backend's test.log and @omega.js/desktop's own dev.log pattern.
|
|
23
|
+
attachLogFile(path.join(process.cwd(), 'logs', 'test.log'));
|
|
24
|
+
|
|
25
|
+
// The local half of the retired `omega setup` (#675) — idempotent, offline,
|
|
26
|
+
// and quiet on a converged target. The gulp verbs get it from the `defaults`
|
|
27
|
+
// task; test runs no gulp, so it calls it here.
|
|
28
|
+
await ensureTarget({
|
|
29
|
+
projectDir: process.cwd(),
|
|
30
|
+
log: (line) => logger.log(line),
|
|
31
|
+
warn: (line) => logger.warn(line),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const layer = options.layer || 'all';
|
|
35
|
+
// Positional target: `npx omega test <target>` where target supports source
|
|
36
|
+
// prefixes — `project:`, `project:<path>`, `em:`, `em:<path>`, or a bare
|
|
37
|
+
// `<path>` (matches both sources). Selects which test FILES run.
|
|
38
|
+
const target = (options._ && options._[1]) || null;
|
|
39
|
+
// `--filter` flag: substring match on test NAMES/descriptions (orthogonal to target).
|
|
40
|
+
const filter = options.filter || null;
|
|
41
|
+
const reporter = options.reporter || 'pretty';
|
|
42
|
+
// Extended mode — opt into tests that hit REAL external services (Firebase, analytics,
|
|
43
|
+
// update feeds) instead of skipping them. Off by default so `npx omega test` stays fast and
|
|
44
|
+
// offline-safe. The canonical signal is the unprefixed `TEST_EXTENDED_MODE` env var — the
|
|
45
|
+
// SAME name across @omega.js/backend, @omega.js/extension, UJM, and @omega.js/desktop (cross-framework parity); `--extended` is the CLI
|
|
46
|
+
// shorthand. Once set on process.env it propagates to every spawned child (electron
|
|
47
|
+
// main/renderer/boot, the gulp boot build) automatically via `{ ...process.env }`.
|
|
48
|
+
const extended = options.extended === true
|
|
49
|
+
|| options.extended === 'true'
|
|
50
|
+
|| process.env.TEST_EXTENDED_MODE === 'true'
|
|
51
|
+
|| process.env.TEST_EXTENDED_MODE === '1';
|
|
52
|
+
|
|
53
|
+
if (extended) {
|
|
54
|
+
process.env.TEST_EXTENDED_MODE = 'true';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// When @omega.js/desktop itself runs its own boot-layer tests (the cwd's package.json is @omega.js/desktop's), there's
|
|
58
|
+
// no real consumer app to boot. Point the boot runner at the fixture under
|
|
59
|
+
// dist/test/fixtures/consumer-app unless the caller has already set OMEGA_TEST_BOOT_PROJECT
|
|
60
|
+
// explicitly. Mirrors BXM's OMEGA_TEST_BOOT_PROJECT / UJM's UJ_TEST_BOOT_PROJECT.
|
|
61
|
+
if (!process.env.OMEGA_TEST_BOOT_PROJECT) {
|
|
62
|
+
try {
|
|
63
|
+
const cwdPkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
|
|
64
|
+
if (cwdPkg.name === '@omega.js/desktop') {
|
|
65
|
+
process.env.OMEGA_TEST_BOOT_PROJECT = path.join(__dirname, '..', 'test', 'fixtures', 'consumer-app');
|
|
66
|
+
}
|
|
67
|
+
} catch (_) { /* no package.json — leave unset */ }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (reporter !== 'json') {
|
|
71
|
+
const parts = [`layer=${layer}`];
|
|
72
|
+
if (target) parts.push(`target="${target}"`);
|
|
73
|
+
if (filter) parts.push(`filter="${filter}"`);
|
|
74
|
+
if (extended) parts.push('+extended');
|
|
75
|
+
logger.log(`Running tests (${parts.join(' ')})`);
|
|
76
|
+
logger.log(`Test mode: ${extended ? 'extended (real external APIs)' : 'normal (external APIs skipped)'}`);
|
|
77
|
+
if (extended) {
|
|
78
|
+
logger.warn(EXTENDED_MODE_WARNING[0]);
|
|
79
|
+
EXTENDED_MODE_WARNING.slice(1).forEach((line) => logger.warn(line));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const result = await run({ layer, target, filter, reporter });
|
|
84
|
+
|
|
85
|
+
if (reporter === 'json') {
|
|
86
|
+
// Final machine-readable summary.
|
|
87
|
+
process.stdout.write(`${JSON.stringify({
|
|
88
|
+
event: 'summary',
|
|
89
|
+
passed: result.passed,
|
|
90
|
+
failed: result.failed,
|
|
91
|
+
skipped: result.skipped,
|
|
92
|
+
total: result.passed + result.failed + result.skipped,
|
|
93
|
+
})}\n`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// A target that named files and matched none is a failed run, not an empty
|
|
97
|
+
// one: a typo'd path, or a suite renamed out from under it, used to report
|
|
98
|
+
// "0 passing" and exit 0
|
|
99
|
+
// ([#814](https://github.com/Omega-JS-Stack/omega/issues/814)).
|
|
100
|
+
if (result.noMatch) {
|
|
101
|
+
logger.error(noMatchMessage(result.noMatch));
|
|
102
|
+
// Standalone that is 1. Inside a brand-root fan-out the manager forwarded
|
|
103
|
+
// ONE target to every target, so a distinct code lets it count this as a
|
|
104
|
+
// miss rather than a failure (#814).
|
|
105
|
+
process.exitCode = noMatchExitCode();
|
|
106
|
+
await attachLogFile.detach();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (result.failed > 0) {
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
await attachLogFile.detach();
|
|
113
|
+
throw new Error(`${result.failed} test(s) failed`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Close test.log before exiting. Nothing to flush: every write already went
|
|
117
|
+
// to the fd synchronously (#197), so the Results block survives the exit
|
|
118
|
+
// below whatever happens — detach() just closes the handle.
|
|
119
|
+
await attachLogFile.detach();
|
|
120
|
+
process.exit(0);
|
|
121
|
+
};
|