@omega.js/extension 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 +194 -0
- package/bin/omega +2 -0
- package/bin/omega-extension +2 -0
- package/bin/omg +2 -0
- package/dist/assets/css/bundles/.gitkeep +0 -0
- package/dist/assets/css/components/content/index.scss +5 -0
- package/dist/assets/css/components/options/index.scss +9 -0
- package/dist/assets/css/components/pages/index.scss +5 -0
- package/dist/assets/css/components/popup/index.scss +9 -0
- package/dist/assets/css/core/_animations.scss +64 -0
- package/dist/assets/css/core/_fontawesome.scss +146 -0
- package/dist/assets/css/core/_initialize.scss +23 -0
- package/dist/assets/css/core/_utilities.scss +80 -0
- package/dist/assets/css/omega-extension.scss +43 -0
- package/dist/assets/css/shell/_index.scss +207 -0
- package/dist/assets/css/tokens/_index.scss +166 -0
- package/dist/assets/js/core/app-shell.js +136 -0
- package/dist/assets/js/libs/initialize-tooltips.js +31 -0
- package/dist/assets/js/libs/recaptcha.js +94 -0
- package/dist/assets/js/main.js +4 -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/background.js +684 -0
- package/dist/build.js +268 -0
- package/dist/cli-run.js +25 -0
- package/dist/cli.js +30 -0
- package/dist/commands/build.js +67 -0
- package/dist/commands/clean.js +29 -0
- package/dist/commands/deploy.js +97 -0
- package/dist/commands/install.js +58 -0
- package/dist/commands/lib/dependencies.js +33 -0
- package/dist/commands/lib/deploy-precheck.js +57 -0
- package/dist/commands/lib/ensure-target.js +151 -0
- package/dist/commands/lib/push-secrets.js +60 -0
- package/dist/commands/migrate.js +77 -0
- package/dist/commands/test.js +110 -0
- package/dist/commands/update.js +21 -0
- package/dist/commands/version.js +12 -0
- package/dist/config/manifest.json +117 -0
- package/dist/config/page-template.html +21 -0
- package/dist/content.js +37 -0
- package/dist/defaults/.github/workflows/publish.yml +86 -0
- package/dist/defaults/.nvmrc +1 -0
- package/dist/defaults/.vscode/settings.json +8 -0
- package/dist/defaults/AGENTS.md +113 -0
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +1 -0
- package/dist/defaults/_.gitignore +75 -0
- package/dist/defaults/config/description.md +46 -0
- package/dist/defaults/config/messages.json +20 -0
- package/dist/defaults/config/omega.json5 +64 -0
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/gulpfile.js +6 -0
- package/dist/defaults/hooks/build/post.js +8 -0
- package/dist/defaults/hooks/build/pre.js +8 -0
- package/dist/defaults/src/assets/css/bundles/.gitkeep +0 -0
- package/dist/defaults/src/assets/css/components/content/index.scss +11 -0
- package/dist/defaults/src/assets/css/components/offscreen/index.scss +4 -0
- package/dist/defaults/src/assets/css/components/options/index.scss +14 -0
- package/dist/defaults/src/assets/css/components/pages/index.scss +10 -0
- package/dist/defaults/src/assets/css/components/popup/index.scss +10 -0
- package/dist/defaults/src/assets/css/components/sidepanel/index.scss +6 -0
- package/dist/defaults/src/assets/css/main.scss +32 -0
- package/dist/defaults/src/assets/images/.gitkeep +0 -0
- package/dist/defaults/src/assets/js/components/background/index.js +25 -0
- package/dist/defaults/src/assets/js/components/content/index.js +22 -0
- package/dist/defaults/src/assets/js/components/offscreen/index.js +25 -0
- package/dist/defaults/src/assets/js/components/options/index.js +22 -0
- package/dist/defaults/src/assets/js/components/pages/index.js +22 -0
- package/dist/defaults/src/assets/js/components/popup/index.js +22 -0
- package/dist/defaults/src/assets/js/components/sidepanel/index.js +20 -0
- package/dist/defaults/src/assets/vendor/.gitkeep +0 -0
- package/dist/defaults/src/manifest.json +131 -0
- package/dist/defaults/src/views/offscreen/index.html +3 -0
- package/dist/defaults/src/views/options/index.html +8 -0
- package/dist/defaults/src/views/pages/index.html +10 -0
- package/dist/defaults/src/views/popup/index.html +4 -0
- package/dist/defaults/src/views/sidepanel/index.html +4 -0
- package/dist/defaults/test/README.md +41 -0
- package/dist/defaults/test/_init.js +10 -0
- package/dist/defaults/test/boot/externally-connectable.test.js +28 -0
- package/dist/gulp/config/locales.js +12 -0
- package/dist/gulp/main.js +78 -0
- package/dist/gulp/tasks/_.js +18 -0
- package/dist/gulp/tasks/audit.js +222 -0
- package/dist/gulp/tasks/bundle.js +687 -0
- package/dist/gulp/tasks/defaults.js +281 -0
- package/dist/gulp/tasks/distribute.js +172 -0
- package/dist/gulp/tasks/fontawesome.js +25 -0
- package/dist/gulp/tasks/html.js +163 -0
- package/dist/gulp/tasks/icons.js +126 -0
- package/dist/gulp/tasks/package.js +742 -0
- package/dist/gulp/tasks/publish.js +417 -0
- package/dist/gulp/tasks/sass.js +252 -0
- package/dist/gulp/tasks/serve.js +103 -0
- package/dist/gulp/tasks/translate.js +252 -0
- package/dist/gulp/tasks/utils/build-json.js +43 -0
- package/dist/gulp/tasks/utils/template-transform.js +50 -0
- package/dist/gulp/templates/BUILD_INSTRUCTIONS.md +69 -0
- package/dist/index.js +46 -0
- package/dist/lib/affiliatizer.js +224 -0
- package/dist/lib/analytics.js +26 -0
- package/dist/lib/auth-helpers.js +213 -0
- package/dist/lib/extension.js +116 -0
- package/dist/lib/icons.js +36 -0
- package/dist/lib/logger-lite.js +35 -0
- package/dist/lib/logger.js +4 -0
- package/dist/lib/messaging.js +48 -0
- package/dist/lib/safe-install.js +4 -0
- package/dist/lib/theme.js +73 -0
- package/dist/lib/verts.js +68 -0
- package/dist/offscreen.js +31 -0
- package/dist/omega-bin.js +6 -0
- package/dist/options.js +80 -0
- package/dist/page.js +80 -0
- package/dist/popup.js +80 -0
- package/dist/sidepanel.js +80 -0
- package/dist/test/assert.js +4 -0
- package/dist/test/fixtures/consumer-extension/dist/background.js +23 -0
- package/dist/test/fixtures/consumer-extension/dist/manifest.json +20 -0
- package/dist/test/fixtures/consumer-extension/dist/options.html +10 -0
- package/dist/test/fixtures/consumer-extension/dist/popup.bundle.js +5 -0
- package/dist/test/fixtures/consumer-extension/dist/popup.html +12 -0
- package/dist/test/harness/extension/background.js +26 -0
- package/dist/test/harness/extension/manifest.json +27 -0
- package/dist/test/harness/extension/options.html +12 -0
- package/dist/test/harness/extension/popup.html +12 -0
- package/dist/test/harness/extension/sidepanel.html +12 -0
- package/dist/test/index.js +63 -0
- package/dist/test/runner.js +99 -0
- package/dist/test/runners/boot.js +221 -0
- package/dist/test/runners/chromium.js +391 -0
- package/dist/test/runners/helpers.js +24 -0
- package/dist/test/suites/background/messaging.test.js +44 -0
- package/dist/test/suites/background/storage.test.js +46 -0
- package/dist/test/suites/background/sw-context.test.js +49 -0
- package/dist/test/suites/boot/build-json-bake.test.js +80 -0
- package/dist/test/suites/boot/extension-loads.test.js +58 -0
- package/dist/test/suites/build/affiliatizer.test.js +64 -0
- package/dist/test/suites/build/app-launch.test.js +65 -0
- package/dist/test/suites/build/attach-log-file.test.js +99 -0
- package/dist/test/suites/build/auth-emulator-gate.test.js +118 -0
- package/dist/test/suites/build/auth-triggers.test.js +71 -0
- package/dist/test/suites/build/boot-discovery.test.js +134 -0
- package/dist/test/suites/build/boot-timeout.test.js +92 -0
- package/dist/test/suites/build/build-error-notification.test.js +122 -0
- package/dist/test/suites/build/build-json-bake.test.js +302 -0
- package/dist/test/suites/build/build-verb.test.js +138 -0
- package/dist/test/suites/build/bundle-targets.test.js +66 -0
- package/dist/test/suites/build/cache-warming.test.js +44 -0
- package/dist/test/suites/build/cli.test.js +150 -0
- package/dist/test/suites/build/default-boot-test.test.js +100 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +287 -0
- package/dist/test/suites/build/deploy-dispatch.test.js +76 -0
- package/dist/test/suites/build/distribute-task.test.js +111 -0
- package/dist/test/suites/build/ensure-target.test.js +141 -0
- package/dist/test/suites/build/env-delivery.test.js +239 -0
- package/dist/test/suites/build/env-watch.test.js +86 -0
- package/dist/test/suites/build/expect.test.js +48 -0
- package/dist/test/suites/build/exports.test.js +53 -0
- package/dist/test/suites/build/extension-fallback.test.js +82 -0
- package/dist/test/suites/build/framework-deps.test.js +176 -0
- package/dist/test/suites/build/global-handlers.test.js +70 -0
- package/dist/test/suites/build/icon-sheet.test.js +74 -0
- package/dist/test/suites/build/logger-lite.test.js +61 -0
- package/dist/test/suites/build/manager.test.js +249 -0
- package/dist/test/suites/build/mode-helpers.test.js +136 -0
- package/dist/test/suites/build/omega-shell.test.js +103 -0
- package/dist/test/suites/build/omega-tokens.test.js +76 -0
- package/dist/test/suites/build/package-task.test.js +831 -0
- package/dist/test/suites/build/setup-scripts.test.js +172 -0
- package/dist/test/suites/build/strip-dev-blocks.test.js +122 -0
- package/dist/test/suites/build/template-replace.test.js +116 -0
- package/dist/test/suites/build/test-discovery.test.js +64 -0
- package/dist/test/suites/build/test-target-no-match.test.js +119 -0
- package/dist/test/suites/build/theme-resolve.test.js +115 -0
- package/dist/test/suites/build/translate.test.js +85 -0
- package/dist/test/suites/build/url-helpers.test.js +119 -0
- package/dist/test/suites/build/verb-logs.test.js +43 -0
- package/dist/test/suites/build/verts-binding.test.js +67 -0
- package/dist/test/suites/build/wakeup-ping.test.js +90 -0
- package/dist/test/suites/build/wave5-messenger.test.js +80 -0
- package/dist/test/suites/view/options-and-sidepanel.test.js +16 -0
- package/dist/test/suites/view/popup-context.test.js +53 -0
- package/dist/test/suites/view/sidepanel.test.js +16 -0
- package/dist/test/utils/extended-mode-warning.js +13 -0
- package/dist/utils/attach-log-file.js +4 -0
- package/dist/utils/mode-helpers.js +117 -0
- package/dist/utils/url-helpers.js +69 -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/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/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/icons.js +178 -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/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -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/translate/cache.js +84 -0
- package/dist/vendor/devkit/translate/engine.js +243 -0
- package/dist/vendor/devkit/translate/index.js +49 -0
- package/dist/vendor/devkit/translate/languages.js +134 -0
- package/dist/vendor/devkit/translate/providers.js +188 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/docs/affiliatizer.md +81 -0
- package/docs/audit.md +67 -0
- package/docs/auth.md +149 -0
- package/docs/build-system.md +176 -0
- package/docs/cdp-debugging.md +42 -0
- package/docs/cli.md +73 -0
- package/docs/common-mistakes.md +10 -0
- package/docs/components.md +87 -0
- package/docs/css.md +133 -0
- package/docs/defaults.md +72 -0
- package/docs/environment-detection.md +79 -0
- package/docs/extension.md +93 -0
- package/docs/hooks.md +111 -0
- package/docs/icons.md +47 -0
- package/docs/index.md +291 -0
- package/docs/logging.md +33 -0
- package/docs/managers.md +100 -0
- package/docs/offscreen.md +57 -0
- package/docs/publishing.md +182 -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/templating.md +66 -0
- package/docs/test-boot-layer.md +143 -0
- package/docs/test-framework.md +411 -0
- package/docs/themes.md +89 -0
- package/docs/translations.md +73 -0
- package/docs/verts.md +67 -0
- package/docs/xss-prevention.md +95 -0
- package/package.json +159 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// View-layer test for the sidepanel context. Most consumers of BXM use
|
|
2
|
+
// chrome.sidePanel for the Chrome 114+ UI panel surface — verify that
|
|
3
|
+
// the test harness can target it just like popup/options.
|
|
4
|
+
|
|
5
|
+
const defineCases = require('../../../vendor/devkit/test/define-cases.js');
|
|
6
|
+
|
|
7
|
+
module.exports = defineCases({
|
|
8
|
+
layer: 'view',
|
|
9
|
+
context: 'sidepanel',
|
|
10
|
+
description: 'view/sidepanel — DOM + context attribute',
|
|
11
|
+
run: async (ctx) => {
|
|
12
|
+
ctx.expect(document.body.dataset.omegaContext).toBe('sidepanel');
|
|
13
|
+
ctx.expect(document.title).toContain('Side Panel');
|
|
14
|
+
ctx.expect(typeof chrome.runtime.id).toBe('string');
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// TEST_EXTENDED_MODE warning — SSOT for consistent messaging.
|
|
2
|
+
//
|
|
3
|
+
// The headline + shape live in @omega.js/devkit (mirrored across @omega.js/backend/EM/UJM); these
|
|
4
|
+
// detail lines describe BXM's blast radius. Used by the test command (printed to
|
|
5
|
+
// console + teed to logs/test.log).
|
|
6
|
+
const { makeExtendedModeWarning } = require('../../vendor/devkit/test/extended-mode-warning.js');
|
|
7
|
+
|
|
8
|
+
const EXTENDED_MODE_WARNING = makeExtendedModeWarning([
|
|
9
|
+
'Tests that hit real external services (Firebase via @omega.js/client, push, any network call) are ENABLED!',
|
|
10
|
+
'This makes real network calls from the background service worker, popup, and content scripts against live backends.',
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
module.exports = { EXTENDED_MODE_WARNING };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Shared devkit module — vendored into dist/vendor/devkit at prepare time by the
|
|
2
|
+
// preparePackage `after` hook. This shim keeps the framework's internal require
|
|
3
|
+
// paths stable while the implementation lives in @omega.js/devkit.
|
|
4
|
+
module.exports = require('../vendor/devkit/attach-log-file.js');
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Runtime mode helpers (@omega.js/backend/EM/UJM-pattern), shared across BXM's eight context Managers
|
|
2
|
+
// (build / background / popup / options / content / sidepanel / page / offscreen).
|
|
3
|
+
//
|
|
4
|
+
// `getEnvironment()` is the SINGLE SOURCE OF TRUTH: it is the ONLY function that reads the
|
|
5
|
+
// raw signals (OMEGA_TEST_MODE / manifest.update_url / OMEGA_BUILD_MODE / NODE_ENV /
|
|
6
|
+
// config.omega.environment) and resolves them to exactly ONE of three mutually-exclusive
|
|
7
|
+
// values. The three is*() checks DERIVE from it — they never read raw signals themselves,
|
|
8
|
+
// so they can never disagree with getEnvironment().
|
|
9
|
+
//
|
|
10
|
+
// isDevelopment() — `getEnvironment() === 'development'`: running unpacked from disk (an
|
|
11
|
+
// unpacked extension via chrome://extensions or a dev build), and NOT
|
|
12
|
+
// testing.
|
|
13
|
+
// isTesting() — `getEnvironment() === 'testing'`: BXM's test framework is running this
|
|
14
|
+
// process (OMEGA_TEST_MODE=true). TAKES PRECEDENCE — a test run is not dev.
|
|
15
|
+
// isProduction() — `getEnvironment() === 'production'`: running from a packed .crx /
|
|
16
|
+
// store-installed extension, and NOT testing. A real positive check —
|
|
17
|
+
// NOT `!isDevelopment()`.
|
|
18
|
+
//
|
|
19
|
+
// To gate "anything non-production" use `!isProduction()` or `isDevelopment() ||
|
|
20
|
+
// isTesting()` intentionally — never assume two values.
|
|
21
|
+
//
|
|
22
|
+
// Context caveat: in build-time Node (gulp / CLI), `chrome` is undefined. getEnvironment()
|
|
23
|
+
// detects via `typeof chrome` so the same code works in every context. Browser detection
|
|
24
|
+
// uses `chrome.runtime.getManifest().update_url` — packed store extensions have one,
|
|
25
|
+
// unpacked ones do not.
|
|
26
|
+
|
|
27
|
+
// getEnvironment() — the SINGLE SOURCE OF TRUTH. Reads every raw signal and resolves to
|
|
28
|
+
// exactly ONE of 'development' | 'testing' | 'production' (mutually exclusive; testing wins).
|
|
29
|
+
// Precedence: testing → production → development.
|
|
30
|
+
function getEnvironment() {
|
|
31
|
+
// 1. Testing wins — set by BXM's test runners / harness, or a testing-baked build.
|
|
32
|
+
// Works in Node (process.env), extension contexts (globalThis set before consumer JS),
|
|
33
|
+
// and config-baked builds (config.omega.environment === 'testing').
|
|
34
|
+
if (typeof process !== 'undefined' && process.env && process.env.OMEGA_TEST_MODE === 'true') return 'testing';
|
|
35
|
+
if (typeof globalThis !== 'undefined' && globalThis.OMEGA_TEST_MODE === true) return 'testing';
|
|
36
|
+
if (this && this.config && this.config.omega && this.config.omega.environment === 'testing') return 'testing';
|
|
37
|
+
|
|
38
|
+
// 2. Browser-side: packed/store extensions have `update_url`; unpacked ones do not.
|
|
39
|
+
// This is the authoritative runtime signal in an extension context.
|
|
40
|
+
if (typeof chrome !== 'undefined' && chrome.runtime && typeof chrome.runtime.getManifest === 'function') {
|
|
41
|
+
try {
|
|
42
|
+
return chrome.runtime.getManifest().update_url ? 'production' : 'development';
|
|
43
|
+
} catch (_) { /* fall through to Node/config signals */ }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 3. Node / build-time + config signals.
|
|
47
|
+
if (process.env.OMEGA_BUILD_MODE === 'true') return 'production';
|
|
48
|
+
if (process.env.NODE_ENV === 'development') return 'development';
|
|
49
|
+
if (this && this.config && this.config.omega && this.config.omega.environment === 'development') return 'development';
|
|
50
|
+
if (this && this.config && this.config.omega && this.config.omega.environment === 'production') return 'production';
|
|
51
|
+
|
|
52
|
+
// 4. Default: development. BXM's deployed artifacts ALWAYS carry their signal — a packed /
|
|
53
|
+
// store extension has `manifest.update_url`, and build-time Node sets OMEGA_BUILD_MODE. So
|
|
54
|
+
// reaching here means a bare tooling / unpacked context, where development is the sensible
|
|
55
|
+
// answer. (Contrast @omega.js/backend/EM, whose deployed RUNTIME can legitimately lack a signal, so they
|
|
56
|
+
// default to production.)
|
|
57
|
+
return 'development';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The three checks DERIVE from getEnvironment() — they never read raw signals, so they can
|
|
61
|
+
// never disagree with it. isDevelopment() is NOT true in testing; isProduction() is a real
|
|
62
|
+
// positive check (never `!isDevelopment()`).
|
|
63
|
+
function isDevelopment() {
|
|
64
|
+
return getEnvironment.call(this) === 'development';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isProduction() {
|
|
68
|
+
return getEnvironment.call(this) === 'production';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isTesting() {
|
|
72
|
+
return getEnvironment.call(this) === 'testing';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// `getVersion()` — returns the extension's version string.
|
|
76
|
+
// 1. `chrome.runtime.getManifest().version` when running inside an extension context.
|
|
77
|
+
// 2. `<cwd>/package.json#version` for build-time scripts.
|
|
78
|
+
// 3. null when neither resolves.
|
|
79
|
+
function getVersion() {
|
|
80
|
+
if (typeof chrome !== 'undefined' && chrome.runtime && typeof chrome.runtime.getManifest === 'function') {
|
|
81
|
+
try {
|
|
82
|
+
return chrome.runtime.getManifest().version || null;
|
|
83
|
+
} catch (_) { /* fall through */ }
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const path = require('path');
|
|
87
|
+
const pkg = require(path.join(process.cwd(), 'package.json'));
|
|
88
|
+
return pkg.version || null;
|
|
89
|
+
} catch (_) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Mix the helpers into a Manager constructor's prototype + the constructor itself
|
|
95
|
+
// (so `Manager.isTesting()` works statically too, matching @omega.js/backend/EM/UJM pattern).
|
|
96
|
+
// getEnvironment() is the SSOT and is attached here too — build.js no longer defines it.
|
|
97
|
+
function attachTo(Manager) {
|
|
98
|
+
Manager.prototype.getEnvironment = getEnvironment;
|
|
99
|
+
Manager.prototype.isDevelopment = isDevelopment;
|
|
100
|
+
Manager.prototype.isProduction = isProduction;
|
|
101
|
+
Manager.prototype.isTesting = isTesting;
|
|
102
|
+
Manager.prototype.getVersion = getVersion;
|
|
103
|
+
Manager.getEnvironment = getEnvironment;
|
|
104
|
+
Manager.isDevelopment = isDevelopment;
|
|
105
|
+
Manager.isProduction = isProduction;
|
|
106
|
+
Manager.isTesting = isTesting;
|
|
107
|
+
Manager.getVersion = getVersion;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
attachTo,
|
|
112
|
+
getEnvironment,
|
|
113
|
+
isDevelopment,
|
|
114
|
+
isProduction,
|
|
115
|
+
isTesting,
|
|
116
|
+
getVersion,
|
|
117
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Backend URL helpers, shared across BXM's context Managers. Mirrors
|
|
2
|
+
// @omega.js/desktop's src/utils/url-helpers.js (the SSOT for this contract) so
|
|
3
|
+
// BXM apps hit the same dev/prod backends as EM and UJM consumers — currently
|
|
4
|
+
// the getApiUrl subset; add the sibling helpers here when a caller needs them.
|
|
5
|
+
//
|
|
6
|
+
// `getEnvironment()` is the SINGLE SOURCE OF TRUTH and lives in
|
|
7
|
+
// src/utils/mode-helpers.js. getApiUrl() routes through `this.getEnvironment()`
|
|
8
|
+
// and resolves to LOCAL urls in BOTH development AND testing — callers normally
|
|
9
|
+
// pass NO argument; an explicit `environment` arg is an override (used mainly by
|
|
10
|
+
// tests to pin a specific environment's mapping).
|
|
11
|
+
//
|
|
12
|
+
// Context caveat: browser extension contexts (service worker, popup, …) have no
|
|
13
|
+
// `process` — the resolved-port env channel (N7) only exists in build-time Node
|
|
14
|
+
// and the test harness. A browser context learns a BUMPED port from the map the
|
|
15
|
+
// build baked into every bundle as OMEGA_BUILD_JSON (`dev.ports`,
|
|
16
|
+
// [#300](https://github.com/Omega-JS-Stack/omega/issues/300)), the same channel
|
|
17
|
+
// background.js reads the auth port from; the classic defaults are the last
|
|
18
|
+
// resort, for a build made with no local stack up.
|
|
19
|
+
|
|
20
|
+
function envPort(name) {
|
|
21
|
+
return typeof process !== 'undefined' && process.env
|
|
22
|
+
? process.env[name]
|
|
23
|
+
: undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// One local port, from whichever channel this context has: the env var first
|
|
27
|
+
// (build-time Node + the test harness), then the baked map
|
|
28
|
+
// ([#744](https://github.com/Omega-JS-Stack/omega/issues/744)).
|
|
29
|
+
function localPort(context, envName, name) {
|
|
30
|
+
return envPort(envName) || context?.config?.dev?.ports?.[name];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getApiUrl(environment) {
|
|
34
|
+
const env = environment || this.getEnvironment();
|
|
35
|
+
|
|
36
|
+
// Local for development OR testing; production otherwise. Mirrors
|
|
37
|
+
// @omega.js/backend's getApiUrl (N7): a published OMEGA_HTTPS_PORT means
|
|
38
|
+
// `mgr serve`'s mkcert proxy is up (https); otherwise plain http to the
|
|
39
|
+
// hosting emulator (env port, baked port, or classic 5002).
|
|
40
|
+
if (env === 'development' || env === 'testing') {
|
|
41
|
+
const httpsPort = localPort(this, 'OMEGA_HTTPS_PORT', 'https');
|
|
42
|
+
return httpsPort
|
|
43
|
+
? `https://localhost:${httpsPort}`
|
|
44
|
+
: `http://localhost:${localPort(this, 'OMEGA_HOSTING_PORT', 'hosting') || 5002}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Prod: api.<brand host>. Mirrors @omega.js/client.getApiUrl. Never derive
|
|
48
|
+
// from authDomain — it is an auth concern (the brand host, with /__/auth/*
|
|
49
|
+
// self-hosted at build time) and must stay free to change independently.
|
|
50
|
+
const brandUrl = this?.config?.brand?.url;
|
|
51
|
+
if (!brandUrl) {
|
|
52
|
+
throw new Error('brand.url not set in config/omega.json5');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `https://api.${new URL(brandUrl).hostname}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Mix the URL helpers into a Manager constructor's prototype + the constructor
|
|
59
|
+
// itself. These call `this.getEnvironment()`, so mode-helpers' attachTo() must
|
|
60
|
+
// run before (or alongside) this one.
|
|
61
|
+
function attachTo(Manager) {
|
|
62
|
+
Manager.prototype.getApiUrl = getApiUrl;
|
|
63
|
+
Manager.getApiUrl = getApiUrl;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
attachTo,
|
|
68
|
+
getApiUrl,
|
|
69
|
+
};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema resolution engine — extracted verbatim from @omega.js/backend's
|
|
3
|
+
* src/manager/helpers/user.js, with ONE change: the '$uuid'/'$randomId'/'$apiKey'
|
|
4
|
+
* value generators are injected via ctx.generators instead of being required
|
|
5
|
+
* in-module. Hosts that can generate them (@omega.js/backend, Node) inject real generators;
|
|
6
|
+
* hosts that can't (@omega.js/client, browser) pass none and the fields resolve to
|
|
7
|
+
* null — the doc's real values always come from the backend.
|
|
8
|
+
*
|
|
9
|
+
* The engine is environment-agnostic: no dependencies, no Node APIs.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if a schema node is a leaf field definition (has 'type' and 'default')
|
|
14
|
+
*/
|
|
15
|
+
function isLeaf(node) {
|
|
16
|
+
return node !== null
|
|
17
|
+
&& typeof node === 'object'
|
|
18
|
+
&& typeof node.type === 'string'
|
|
19
|
+
&& 'default' in node;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Coerce a value to the expected type. Returns the coerced value or undefined if coercion fails.
|
|
24
|
+
*/
|
|
25
|
+
function coerce(value, type) {
|
|
26
|
+
if (typeof value === type) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'number': {
|
|
32
|
+
const n = Number(value);
|
|
33
|
+
return Number.isNaN(n) ? undefined : n;
|
|
34
|
+
}
|
|
35
|
+
case 'boolean': {
|
|
36
|
+
if (value === 'true' || value === 1) return true;
|
|
37
|
+
if (value === 'false' || value === 0) return false;
|
|
38
|
+
return Boolean(value);
|
|
39
|
+
}
|
|
40
|
+
case 'string': {
|
|
41
|
+
return String(value);
|
|
42
|
+
}
|
|
43
|
+
default: {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a single leaf field value
|
|
51
|
+
*/
|
|
52
|
+
function resolveLeaf(leaf, value, ctx) {
|
|
53
|
+
// Null handling
|
|
54
|
+
if (value === null) {
|
|
55
|
+
return leaf.nullable ? null : resolveDefault(leaf.default, ctx);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Undefined → apply default
|
|
59
|
+
if (value === undefined) {
|
|
60
|
+
return resolveDefault(leaf.default, ctx);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Array type — just check it's an array, don't coerce
|
|
64
|
+
if (leaf.type === 'array') {
|
|
65
|
+
return Array.isArray(value) ? value : resolveDefault(leaf.default, ctx);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Type coercion
|
|
69
|
+
if (typeof value !== leaf.type) {
|
|
70
|
+
const coerced = coerce(value, leaf.type);
|
|
71
|
+
return coerced !== undefined ? coerced : resolveDefault(leaf.default, ctx);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a default value, handling special tokens
|
|
79
|
+
*/
|
|
80
|
+
function resolveDefault(def, ctx) {
|
|
81
|
+
if (typeof def !== 'string' || !def.startsWith('$')) {
|
|
82
|
+
// For arrays, return a fresh copy to avoid shared references
|
|
83
|
+
if (Array.isArray(def)) {
|
|
84
|
+
return [...def];
|
|
85
|
+
}
|
|
86
|
+
return def;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
switch (def) {
|
|
90
|
+
case '$uuid':
|
|
91
|
+
return ctx.generators.uuid ? ctx.generators.uuid() : null;
|
|
92
|
+
case '$randomId':
|
|
93
|
+
return ctx.generators.randomId ? ctx.generators.randomId() : null;
|
|
94
|
+
case '$apiKey':
|
|
95
|
+
return ctx.generators.apiKey ? ctx.generators.apiKey() : null;
|
|
96
|
+
case '$oldDate':
|
|
97
|
+
return ctx.oldDate;
|
|
98
|
+
case '$oldDateUNIX':
|
|
99
|
+
return ctx.oldDateUNIX;
|
|
100
|
+
case '$now':
|
|
101
|
+
return ctx.now;
|
|
102
|
+
case '$nowUNIX':
|
|
103
|
+
return ctx.nowUNIX;
|
|
104
|
+
default:
|
|
105
|
+
return def;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Expand $timestamp shorthand into a schema branch
|
|
111
|
+
*/
|
|
112
|
+
function expandTimestamp(variant) {
|
|
113
|
+
const useNow = variant === '$timestamp:now';
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
timestamp: { type: 'string', default: useNow ? '$now' : '$oldDate' },
|
|
117
|
+
timestampUNIX: { type: 'number', default: useNow ? '$nowUNIX' : 0 },
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Recursively resolve a schema node against input data
|
|
123
|
+
*/
|
|
124
|
+
function resolve(schema, data, ctx) {
|
|
125
|
+
data = data || {};
|
|
126
|
+
const result = {};
|
|
127
|
+
|
|
128
|
+
// If $passthrough, start by copying all existing keys from data
|
|
129
|
+
const isPassthrough = schema.$passthrough === true;
|
|
130
|
+
const template = schema.$template || null;
|
|
131
|
+
|
|
132
|
+
if (isPassthrough) {
|
|
133
|
+
// Copy all data keys first (they'll be overwritten by defined schema fields below)
|
|
134
|
+
for (const key of Object.keys(data)) {
|
|
135
|
+
if (template && !key.startsWith('$') && !(key in schema)) {
|
|
136
|
+
// Dynamic key — resolve against template
|
|
137
|
+
result[key] = resolve(template, data[key], ctx);
|
|
138
|
+
} else if (!(key in schema) || key.startsWith('$')) {
|
|
139
|
+
// Unknown key not in schema — passthrough as-is
|
|
140
|
+
result[key] = data[key];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Now resolve each defined schema field
|
|
146
|
+
for (const [key, node] of Object.entries(schema)) {
|
|
147
|
+
// Skip meta keys
|
|
148
|
+
if (key.startsWith('$')) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Handle string shorthands
|
|
153
|
+
if (typeof node === 'string') {
|
|
154
|
+
if (node === '$template') {
|
|
155
|
+
// Resolve against parent's $template
|
|
156
|
+
result[key] = resolve(template, data[key], ctx);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (node.startsWith('$timestamp')) {
|
|
160
|
+
// Expand timestamp shorthand and recurse
|
|
161
|
+
result[key] = resolve(expandTimestamp(node), data[key], ctx);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Leaf field
|
|
167
|
+
if (isLeaf(node)) {
|
|
168
|
+
result[key] = resolveLeaf(node, data[key], ctx);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Nested branch (plain object)
|
|
173
|
+
if (node !== null && typeof node === 'object') {
|
|
174
|
+
result[key] = resolve(node, data[key], ctx);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = { resolve };
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* features.js — the ONE reading of the features contract
|
|
3
|
+
* ([#647](https://github.com/Omega-JS-Stack/omega/issues/647)).
|
|
4
|
+
*
|
|
5
|
+
* A feature is DEFINED once, in the config's top-level `features` catalog:
|
|
6
|
+
*
|
|
7
|
+
* features: {
|
|
8
|
+
* saves: { name: 'Saves', icon: 'feather', definition: '…',
|
|
9
|
+
* usage: { pace: 'daily', mirror: ['teams'] } },
|
|
10
|
+
* support: { name: 'Priority support', icon: 'headset' },
|
|
11
|
+
* }
|
|
12
|
+
*
|
|
13
|
+
* A `usage` block makes the entry COUNTED (metered per user); an entry without
|
|
14
|
+
* one is a PERK, never counted. Each product then names only its VALUE:
|
|
15
|
+
* `features: { saves: 100, support: true }` — a number on a counted feature
|
|
16
|
+
* (the MONTHLY limit, -1 unlimited), true/false/a string on a perk.
|
|
17
|
+
*
|
|
18
|
+
* This module is the shared home of every derivation both sides make from
|
|
19
|
+
* those two halves plus a user's stored counters — the backend's `consume`
|
|
20
|
+
* gate and the browser's account page must never disagree about what a user's
|
|
21
|
+
* limit is:
|
|
22
|
+
* - the EFFECTIVE limit, where an admin-written `usage.overrides.<feature>`
|
|
23
|
+
* on the user doc wins over the plan's number;
|
|
24
|
+
* - the DAY share, `ceil(limit / days in this month)`, so a monthly quota
|
|
25
|
+
* cannot be burned on day one (pacing is the default; `pace: false` opts
|
|
26
|
+
* out to a plain monthly counter);
|
|
27
|
+
* - the two counters a counted feature carries per user, month and day.
|
|
28
|
+
*
|
|
29
|
+
* -1 is the unlimited sentinel everywhere it can appear: a limit, a day share,
|
|
30
|
+
* and a remaining count.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// Where a user's counters and overrides live on the account document.
|
|
34
|
+
const USAGE_KEY = 'usage';
|
|
35
|
+
const OVERRIDES_KEY = 'overrides';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Is this catalog entry COUNTED? A `usage` block is what meters a feature;
|
|
39
|
+
* everything else is a perk the plan either includes or does not.
|
|
40
|
+
* @param {object} entry - a top-level `features` catalog entry
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
function isCountedFeature(entry) {
|
|
44
|
+
return !!(entry && typeof entry === 'object' && entry.usage && typeof entry.usage === 'object' && !Array.isArray(entry.usage));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Is this feature paced by day? Pacing is the DEFAULT on every counted
|
|
49
|
+
* feature; `usage: { pace: false }` opts out to a plain monthly counter.
|
|
50
|
+
* @param {object} entry - a catalog entry
|
|
51
|
+
* @returns {boolean}
|
|
52
|
+
*/
|
|
53
|
+
function isPacedFeature(entry) {
|
|
54
|
+
return isCountedFeature(entry) && entry.usage.pace !== false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The document kinds a counted feature's counters mirror onto, declared in the
|
|
59
|
+
* catalog rather than at the call site.
|
|
60
|
+
* @param {object} entry - a catalog entry
|
|
61
|
+
* @returns {string[]} the declared kinds, or []
|
|
62
|
+
*/
|
|
63
|
+
function featureMirrors(entry) {
|
|
64
|
+
return isCountedFeature(entry) && Array.isArray(entry.usage.mirror) ? entry.usage.mirror : [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Days in the month the given date falls in.
|
|
69
|
+
* @param {Date} [date] - defaults to now
|
|
70
|
+
* @returns {number}
|
|
71
|
+
*/
|
|
72
|
+
function daysInMonth(date) {
|
|
73
|
+
const d = date || new Date();
|
|
74
|
+
return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A month limit's share of ONE day: ceil(limit / days in this month), so a
|
|
79
|
+
* quota of 100 in a 31-day month allows 4 a day and never 100 on the 1st.
|
|
80
|
+
* Unlimited stays unlimited; nothing stays nothing.
|
|
81
|
+
* @param {number} limit - the effective MONTHLY limit (-1 unlimited)
|
|
82
|
+
* @param {Date} [date] - the day being paced, defaults to now
|
|
83
|
+
* @returns {number} the day's share (-1 unlimited)
|
|
84
|
+
*/
|
|
85
|
+
function dayShare(limit, date) {
|
|
86
|
+
if (!Number.isFinite(limit) || limit === 0) return 0;
|
|
87
|
+
if (limit < 0) return -1;
|
|
88
|
+
return Math.ceil(limit / daysInMonth(date));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The per-user override for a feature, when the account carries one. Written
|
|
93
|
+
* by admins only (the user doc's `usage` key is a framework field the security
|
|
94
|
+
* rules deny a client), and it WINS over the plan's number — extra credits
|
|
95
|
+
* granted to one account, not a second pricing tier.
|
|
96
|
+
* @param {object} account - the user document
|
|
97
|
+
* @param {string} id - feature id
|
|
98
|
+
* @returns {number|null} the override, or null when there is none
|
|
99
|
+
*/
|
|
100
|
+
function featureOverride(account, id) {
|
|
101
|
+
const value = account && account[USAGE_KEY] && account[USAGE_KEY][OVERRIDES_KEY]
|
|
102
|
+
? account[USAGE_KEY][OVERRIDES_KEY][id]
|
|
103
|
+
: undefined;
|
|
104
|
+
|
|
105
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* What a product promises for one feature: its raw value from the product's
|
|
110
|
+
* `features` map. A product that never names the feature promises nothing.
|
|
111
|
+
* @param {object} product - a `payment.products` entry
|
|
112
|
+
* @param {string} id - feature id
|
|
113
|
+
* @returns {*} the value, or undefined
|
|
114
|
+
*/
|
|
115
|
+
function productFeatureValue(product, id) {
|
|
116
|
+
const values = product && product.features;
|
|
117
|
+
return values && typeof values === 'object' && !Array.isArray(values) ? values[id] : undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The counters a user carries for one feature. The stored shape is
|
|
122
|
+
* `usage.<id>.{ monthly, daily, total, last }` — monthly and daily are the two
|
|
123
|
+
* the gate reads, total never resets, last records when it moved.
|
|
124
|
+
* @param {object} account - the user document
|
|
125
|
+
* @param {string} id - feature id
|
|
126
|
+
* @returns {{ monthly: number, daily: number, total: number }}
|
|
127
|
+
*/
|
|
128
|
+
function featureCounters(account, id) {
|
|
129
|
+
const stored = (account && account[USAGE_KEY] && account[USAGE_KEY][id]) || {};
|
|
130
|
+
const read = (key) => (typeof stored[key] === 'number' && Number.isFinite(stored[key]) ? stored[key] : 0);
|
|
131
|
+
|
|
132
|
+
return { monthly: read('monthly'), daily: read('daily'), total: read('total') };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* How many of a limit are left, given what is used. Unlimited stays unlimited.
|
|
137
|
+
* @param {number} limit - the limit (-1 unlimited)
|
|
138
|
+
* @param {number} used - the counter
|
|
139
|
+
* @returns {number} what remains (-1 unlimited), never below zero
|
|
140
|
+
*/
|
|
141
|
+
function remaining(limit, used) {
|
|
142
|
+
if (limit < 0) return -1;
|
|
143
|
+
return Math.max(0, limit - used);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Resolve ONE feature against a catalog, a product and an account: everything
|
|
148
|
+
* a gate or an account page needs to speak about it in one object.
|
|
149
|
+
*
|
|
150
|
+
* @param {string} id - feature id
|
|
151
|
+
* @param {object} options
|
|
152
|
+
* @param {object} [options.catalog] - the top-level `features` catalog
|
|
153
|
+
* @param {object} [options.product] - the account's resolved product
|
|
154
|
+
* @param {object} [options.account] - the user document (counters + overrides)
|
|
155
|
+
* @param {Date} [options.now] - the day being paced, defaults to now
|
|
156
|
+
* @returns {object} { id, name, icon, definition, counted, paced, mirror,
|
|
157
|
+
* value, limit, planLimit, override, used, left, total,
|
|
158
|
+
* day: { limit, used, left } }
|
|
159
|
+
*/
|
|
160
|
+
function resolveFeature(id, options) {
|
|
161
|
+
options = options || {};
|
|
162
|
+
|
|
163
|
+
const entry = (options.catalog || {})[id] || null;
|
|
164
|
+
const counted = isCountedFeature(entry);
|
|
165
|
+
const value = productFeatureValue(options.product, id);
|
|
166
|
+
const counters = featureCounters(options.account, id);
|
|
167
|
+
const override = featureOverride(options.account, id);
|
|
168
|
+
|
|
169
|
+
const planLimit = counted && typeof value === 'number' ? value : 0;
|
|
170
|
+
const limit = counted && override !== null ? override : planLimit;
|
|
171
|
+
const paced = isPacedFeature(entry);
|
|
172
|
+
const dayLimit = paced ? dayShare(limit, options.now) : -1;
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
id: id,
|
|
176
|
+
name: (entry && entry.name) || id,
|
|
177
|
+
icon: (entry && entry.icon) || null,
|
|
178
|
+
definition: (entry && entry.definition) || null,
|
|
179
|
+
counted: counted,
|
|
180
|
+
paced: paced,
|
|
181
|
+
mirror: featureMirrors(entry),
|
|
182
|
+
value: counted ? limit : value,
|
|
183
|
+
limit: limit,
|
|
184
|
+
planLimit: planLimit,
|
|
185
|
+
override: override,
|
|
186
|
+
used: counters.monthly,
|
|
187
|
+
left: remaining(limit, counters.monthly),
|
|
188
|
+
total: counters.total,
|
|
189
|
+
day: {
|
|
190
|
+
limit: dayLimit,
|
|
191
|
+
used: counters.daily,
|
|
192
|
+
left: remaining(dayLimit, counters.daily),
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Resolve every feature the catalog defines, in CATALOG order — the row order
|
|
199
|
+
* every surface renders (pricing rows, account bars).
|
|
200
|
+
* @param {object} options - same options as resolveFeature
|
|
201
|
+
* @returns {object[]} one resolved feature per catalog entry
|
|
202
|
+
*/
|
|
203
|
+
function resolveFeatures(options) {
|
|
204
|
+
options = options || {};
|
|
205
|
+
|
|
206
|
+
return Object.keys(options.catalog || {}).map((id) => resolveFeature(id, options));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
module.exports = {
|
|
210
|
+
isCountedFeature,
|
|
211
|
+
isPacedFeature,
|
|
212
|
+
featureMirrors,
|
|
213
|
+
featureOverride,
|
|
214
|
+
featureCounters,
|
|
215
|
+
productFeatureValue,
|
|
216
|
+
daysInMonth,
|
|
217
|
+
dayShare,
|
|
218
|
+
resolveFeature,
|
|
219
|
+
resolveFeatures,
|
|
220
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @omega.js/account — the single source of truth for the OMEGA user/account schema.
|
|
3
|
+
*
|
|
4
|
+
* Today the account shape lives in two drifted places: @omega.js/backend's
|
|
5
|
+
* src/manager/helpers/user.js (canonical — schema engine + tokens) and
|
|
6
|
+
* @omega.js/client's DEFAULT_ACCOUNT in modules/auth.js (hand-rolled deep-merge,
|
|
7
|
+
* missing flags/activity/personal branches and `everPaid`). This package
|
|
8
|
+
* unifies them; each framework becomes a thin wrapper (@omega.js/backend keeps its
|
|
9
|
+
* `new User(Manager, settings).properties` API, @omega.js/client keeps
|
|
10
|
+
* `resolveAccount(rawData, firebaseUser)`).
|
|
11
|
+
*
|
|
12
|
+
* resolveAccount(data, options):
|
|
13
|
+
* options.generators — { uuid, randomId, apiKey } value generators for the
|
|
14
|
+
* '$uuid'/'$randomId'/'$apiKey' schema tokens. @omega.js/backend injects real ones
|
|
15
|
+
* (uuid v4, Utilities().randomId, uid-generator); the frontend passes none
|
|
16
|
+
* and the fields resolve to null (real values always come from the backend).
|
|
17
|
+
* options.user — optional auth-user overlay ({ uid, email }): fills
|
|
18
|
+
* account.auth identity when the doc doesn't carry it (@omega.js/client's
|
|
19
|
+
* resolveAccount(rawData, firebaseUser) semantic).
|
|
20
|
+
*/
|
|
21
|
+
const USER_SCHEMA = require('./schema.js');
|
|
22
|
+
const { resolve } = require('./engine.js');
|
|
23
|
+
const resolveSubscription = require('./subscription.js');
|
|
24
|
+
const features = require('./features.js');
|
|
25
|
+
|
|
26
|
+
function resolveAccount(data, options) {
|
|
27
|
+
options = options || {};
|
|
28
|
+
|
|
29
|
+
// Time context — byte-identical to @omega.js/backend's node-powertools timestamps:
|
|
30
|
+
// powertools.timestamp(d, { output: 'string' }) === d.toISOString(),
|
|
31
|
+
// powertools.timestamp(d, { output: 'unix' }) === floor(ms / 1000).
|
|
32
|
+
const now = new Date();
|
|
33
|
+
const ctx = {
|
|
34
|
+
generators: options.generators || {},
|
|
35
|
+
now: now.toISOString(),
|
|
36
|
+
nowUNIX: Math.floor(now.getTime() / 1000),
|
|
37
|
+
oldDate: new Date(0).toISOString(),
|
|
38
|
+
oldDateUNIX: 0,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const account = resolve(USER_SCHEMA, data || {}, ctx);
|
|
42
|
+
|
|
43
|
+
// Auth-user overlay (frontend semantic): identity from the signed-in Firebase
|
|
44
|
+
// user when the stored doc doesn't already carry it
|
|
45
|
+
if (options.user) {
|
|
46
|
+
account.auth.uid = account.auth.uid || options.user.uid || null;
|
|
47
|
+
account.auth.email = account.auth.email || options.user.email || null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return account;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { USER_SCHEMA, resolveAccount, resolveSubscription, ...features };
|