@salesforce/ui-bundle-template-feature-angular-language-switcher 12.5.4
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.txt +82 -0
- package/README.md +193 -0
- package/dist/.forceignore +15 -0
- package/dist/.husky/pre-commit +4 -0
- package/dist/.prettierignore +11 -0
- package/dist/.prettierrc +17 -0
- package/dist/CHANGELOG.md +5238 -0
- package/dist/README.md +77 -0
- package/dist/config/project-scratch-def.json +13 -0
- package/dist/eslint.config.js +7 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.forceignore +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.graphqlrc.yml +2 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.postcssrc.json +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.prettierignore +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.prettierrc +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/CHANGELOG.md +4 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/README.md +85 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/angular.json +98 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/codegen.yml +95 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/components.json +6 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/e2e/app.spec.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/esbuild/api-version.mjs +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/esbuild/graphql-codegen.mjs +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/eslint-plugin-angular-graphql.js +148 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/eslint.config.js +76 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/feature-angular-language-switcher.uibundle-meta.xml +7 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/middleware/html.mjs +3 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/middleware/proxy.mjs +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/package.json +69 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/playwright.config.ts +25 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/public/favicon.ico +0 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/scripts/get-graphql-schema.mjs +69 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/scripts/rewrite-e2e-assets.mjs +30 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/api/data-client.service.spec.ts +184 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/api/data-client.service.ts +74 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.config.ts +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.html +1 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.routes.ts +26 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.spec.ts +18 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.html +51 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.spec.ts +63 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.ts +27 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/alert/alert.html +27 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/alert/alert.ts +41 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/button/button.html +27 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/button/button.ts +66 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/card/card.ts +100 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/collapsible/collapsible.html +38 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/collapsible/collapsible.ts +21 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-picker/date-picker.html +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-picker/date-picker.ts +49 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-range-picker/date-range-picker.html +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-range-picker/date-range-picker.ts +69 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dialog/dialog.html +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dialog/dialog.ts +40 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dropdown-menu/dropdown-menu.html +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dropdown-menu/dropdown-menu.ts +100 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field/field.html +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field/field.ts +28 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field-appearance.ts +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field-size.ts +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/icon/icon.ts +68 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/input/input.html +34 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/input/input.ts +79 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/label/label.ts +21 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/paginator.html +74 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/paginator.ts +93 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/types.ts +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/popover/popover.html +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/popover/popover.ts +37 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/select/select.html +36 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/select/select.ts +63 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/separator/separator.ts +31 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/skeleton/skeleton.ts +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/spinner/spinner.ts +28 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/html-middleware-site-example.ts +41 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/language-switcher-example.ts +41 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/build-language-url.ts +158 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/index.ts +28 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/language-switcher.html +22 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/language-switcher.ts +110 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/languages.ts +46 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.html +6 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.spec.ts +23 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.ts +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.html +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.spec.ts +33 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-action.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-description.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-title.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert.ts +35 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/index.ts +16 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/hlm-button.token.ts +22 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/hlm-button.ts +72 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/index.ts +6 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar-multi.ts +195 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar-range.ts +194 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar.ts +189 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-month-year-calendar.ts +119 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/index.ts +16 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-action.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-avatar.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-description.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-footer.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-header.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-title.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card.token.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card.ts +22 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/index.ts +28 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible-content.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible-trigger.ts +9 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/index.ts +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-multi-input.ts +104 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-anchor.ts +23 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-input.ts +118 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-multi.token.ts +109 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-multi.ts +220 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-trigger.ts +104 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker.token.ts +69 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker.ts +203 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-input.ts +120 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-picker.token.ts +86 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-picker.ts +252 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-input.ts +105 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-picker.token.ts +89 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-picker.ts +196 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/index.ts +38 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-close.ts +9 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-content.ts +74 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-description.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-footer.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-header.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-overlay.ts +27 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-title.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-trigger.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog.service.ts +46 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog.ts +24 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/index.ts +35 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox-indicator.ts +21 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox.ts +54 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-focus-on-hover.ts +35 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-group.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-item-sub-indicator.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-item.ts +42 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-label.ts +20 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio-indicator.ts +21 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio.ts +49 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-separator.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-shortcut.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub-trigger.ts +52 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub.ts +53 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-token.ts +26 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-trigger.ts +46 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu.ts +57 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/index.ts +49 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-description.ts +53 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-error.ts +100 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-group.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-label.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-legend.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-separator.ts +24 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-set.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-title.ts +15 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field.ts +47 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/index.ts +34 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input/hlm-input.ts +21 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-addon.ts +40 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-button.ts +47 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-input.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-text.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group.ts +18 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/index.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/hlm-label.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/label.html +11 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-numbered-pagination-query-params.ts +191 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-numbered-pagination.ts +290 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-content.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-ellipsis.ts +27 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-item.ts +7 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-link.ts +51 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-next.ts +65 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-previous.ts +65 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/index.ts +31 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-content.ts +25 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-description.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-header.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-title.ts +12 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-trigger.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover.ts +23 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/index.ts +25 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-content.ts +44 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-group.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-item.ts +36 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-label.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-multiple.ts +37 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-placeholder.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-portal.ts +8 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-scroll-down.ts +22 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-scroll-up.ts +22 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-separator.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-trigger.ts +59 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-value-template.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-value.ts +18 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-values-content.ts +9 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-values.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select.ts +37 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/index.ts +52 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/separator/hlm-separator.ts +19 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/separator/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/skeleton/hlm-skeleton.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/skeleton/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/spinner/hlm-spinner.ts +26 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/spinner/index.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/hlm.ts +313 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/index.ts +2 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/provide-spartan-hlm.ts +34 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/utils/async-data.ts +99 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/index.html +13 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/main.ts +5 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/styles.css +139 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/types/sf-globals.d.ts +23 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.app.json +11 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.json +36 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.spec.json +10 -0
- package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/ui-bundle.json +7 -0
- package/dist/jest.config.js +6 -0
- package/dist/package-lock.json +12554 -0
- package/dist/package.json +46 -0
- package/dist/scripts/apex/hello.apex +10 -0
- package/dist/scripts/gitignore-templates.json +4 -0
- package/dist/scripts/graphql-search.sh +191 -0
- package/dist/scripts/org-setup-config-schema.mjs +132 -0
- package/dist/scripts/org-setup-dev.mjs +114 -0
- package/dist/scripts/org-setup-url.mjs +108 -0
- package/dist/scripts/org-setup-utils.mjs +569 -0
- package/dist/scripts/org-setup-xml.mjs +278 -0
- package/dist/scripts/org-setup.config.json +5 -0
- package/dist/scripts/org-setup.mjs +2537 -0
- package/dist/scripts/sf-project-setup.mjs +103 -0
- package/dist/scripts/soql/account.soql +6 -0
- package/dist/scripts/validate-org-setup-config.mjs +38 -0
- package/dist/sfdx-project.json +12 -0
- package/package.json +46 -0
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/eslint.config.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import js from '@eslint/js';
|
|
4
|
+
import angular from 'angular-eslint';
|
|
5
|
+
import tseslint from 'typescript-eslint';
|
|
6
|
+
import { createPlugin } from './eslint-plugin-angular-graphql.js';
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const schemaPath = resolve(__dirname, '../../../../../schema.graphql');
|
|
10
|
+
const angularGraphqlPlugin = createPlugin({ schemaPath });
|
|
11
|
+
|
|
12
|
+
export default tseslint.config(
|
|
13
|
+
// Global ignores
|
|
14
|
+
{
|
|
15
|
+
ignores: [
|
|
16
|
+
'dist/**/*',
|
|
17
|
+
'.angular/**/*',
|
|
18
|
+
'coverage/**/*',
|
|
19
|
+
'node_modules/**/*',
|
|
20
|
+
// Vendored Spartan primitives use upstream hlm*/brn* selectors and are
|
|
21
|
+
// not authored here, so they can't satisfy the app-prefix/a11y rules.
|
|
22
|
+
'**/shared/**',
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
// TypeScript files
|
|
26
|
+
{
|
|
27
|
+
files: ['**/*.ts'],
|
|
28
|
+
extends: [
|
|
29
|
+
js.configs.recommended,
|
|
30
|
+
...tseslint.configs.recommended,
|
|
31
|
+
...angular.configs.tsRecommended,
|
|
32
|
+
],
|
|
33
|
+
rules: {
|
|
34
|
+
'@angular-eslint/directive-selector': [
|
|
35
|
+
'error',
|
|
36
|
+
{
|
|
37
|
+
type: 'attribute',
|
|
38
|
+
prefix: 'app',
|
|
39
|
+
style: 'camelCase',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
'@angular-eslint/component-selector': [
|
|
43
|
+
'error',
|
|
44
|
+
{
|
|
45
|
+
type: 'element',
|
|
46
|
+
prefix: 'app',
|
|
47
|
+
style: 'kebab-case',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
// The UI wrapper components (app-button, app-card, …) intentionally
|
|
51
|
+
// alias an input to `class` so callers can write `class="…"` on the host
|
|
52
|
+
// and have it forward to the inner Material element. Allow that one name.
|
|
53
|
+
'@angular-eslint/no-input-rename': ['error', { allowedNames: ['class'] }],
|
|
54
|
+
'@typescript-eslint/no-unused-vars': [
|
|
55
|
+
'error',
|
|
56
|
+
{
|
|
57
|
+
argsIgnorePattern: '^_',
|
|
58
|
+
varsIgnorePattern: '^_',
|
|
59
|
+
caughtErrorsIgnorePattern: '^_',
|
|
60
|
+
ignoreRestSiblings: true,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
64
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
65
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
// Template files
|
|
69
|
+
{
|
|
70
|
+
files: ['**/*.html'],
|
|
71
|
+
extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
|
|
72
|
+
rules: {},
|
|
73
|
+
},
|
|
74
|
+
// Inline template processor + GraphQL rules (plugin handles schema detection)
|
|
75
|
+
...angularGraphqlPlugin.configs,
|
|
76
|
+
);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
|
+
<masterLabel>feature-angular-language-switcher</masterLabel>
|
|
4
|
+
<description>A Salesforce UI Bundle.</description>
|
|
5
|
+
<isActive>true</isActive>
|
|
6
|
+
<version>1</version>
|
|
7
|
+
</UIBundle>
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/middleware/proxy.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy middleware for Angular CLI dev server.
|
|
3
|
+
*
|
|
4
|
+
* Forwards `/services/*` and other manifest-routed paths to the connected
|
|
5
|
+
* Salesforce org with authentication. Watches `ui-bundle.json` for changes
|
|
6
|
+
* and recreates the proxy handler automatically (manual browser refresh needed).
|
|
7
|
+
*
|
|
8
|
+
* Referenced from angular.json: architect.serve.options.middlewares[].
|
|
9
|
+
*/
|
|
10
|
+
import { createProxyMiddleware } from '@salesforce/angular-plugin-ui-bundle';
|
|
11
|
+
|
|
12
|
+
export default await createProxyMiddleware();
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base-angular-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "sf-angular-serve",
|
|
11
|
+
"dev:design": "sf-angular-serve --design",
|
|
12
|
+
"build": "ng lint && ng build",
|
|
13
|
+
"watch": "ng build --watch --configuration development",
|
|
14
|
+
"test": "ng test",
|
|
15
|
+
"lint": "ng lint",
|
|
16
|
+
"build:e2e": "ng lint && ng build && node scripts/rewrite-e2e-assets.mjs",
|
|
17
|
+
"e2e": "playwright test",
|
|
18
|
+
"graphql:schema": "node scripts/get-graphql-schema.mjs",
|
|
19
|
+
"graphql:codegen": "graphql-codegen"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@angular/cdk": "^21.2.0",
|
|
23
|
+
"@angular/common": "^21.2.0",
|
|
24
|
+
"@angular/compiler": "^21.2.0",
|
|
25
|
+
"@angular/core": "^21.2.0",
|
|
26
|
+
"@angular/forms": "^21.2.0",
|
|
27
|
+
"@angular/platform-browser": "^21.2.0",
|
|
28
|
+
"@angular/router": "^21.2.0",
|
|
29
|
+
"@ng-icons/core": "^32.2.0",
|
|
30
|
+
"@ng-icons/lucide": "^32.2.0",
|
|
31
|
+
"@salesforce/angular-plugin-ui-bundle": "^12.5.4",
|
|
32
|
+
"@salesforce/platform-sdk": "^12.5.4",
|
|
33
|
+
"@spartan-ng/brain": "^1.3.1",
|
|
34
|
+
"class-variance-authority": "^0.7.1",
|
|
35
|
+
"clsx": "^2.1.1",
|
|
36
|
+
"rxjs": "~7.8.0",
|
|
37
|
+
"tailwind-merge": "^3.5.0",
|
|
38
|
+
"tslib": "^2.3.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@angular-builders/custom-esbuild": "^21.0.0",
|
|
42
|
+
"@angular-eslint/builder": "^21.0.0",
|
|
43
|
+
"@angular/build": "^21.2.11",
|
|
44
|
+
"@angular/cli": "^21.2.11",
|
|
45
|
+
"@angular/compiler-cli": "^21.2.0",
|
|
46
|
+
"@eslint/js": "^9.0.0",
|
|
47
|
+
"@graphql-codegen/cli": "^6.1.0",
|
|
48
|
+
"@graphql-codegen/typescript-operations": "^5.0.6",
|
|
49
|
+
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
|
50
|
+
"@playwright/test": "^1.49.0",
|
|
51
|
+
"@spartan-ng/cli": "^1.3.1",
|
|
52
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
53
|
+
"angular-eslint": "^21.0.0",
|
|
54
|
+
"eslint": "^9.0.0",
|
|
55
|
+
"graphql": "^16.11.0",
|
|
56
|
+
"graphql-codegen-typescript-operation-types": "^2.0.2",
|
|
57
|
+
"jsdom": "^28.0.0",
|
|
58
|
+
"postcss": "^8.5.0",
|
|
59
|
+
"serve": "^14.2.5",
|
|
60
|
+
"tailwindcss": "^4.0.0",
|
|
61
|
+
"typescript": "~5.9.2",
|
|
62
|
+
"typescript-eslint": "^8.0.0",
|
|
63
|
+
"vitest": "^4.1.0",
|
|
64
|
+
"@salesforce/graphiti": "^12.5.4"
|
|
65
|
+
},
|
|
66
|
+
"overrides": {
|
|
67
|
+
"undici": "^7.28.0"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/playwright.config.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
const E2E_PORT = 5176;
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
testDir: './e2e',
|
|
7
|
+
fullyParallel: true,
|
|
8
|
+
forbidOnly: !!process.env.CI,
|
|
9
|
+
retries: process.env.CI ? 2 : 0,
|
|
10
|
+
workers: process.env.CI ? 1 : undefined,
|
|
11
|
+
reporter: 'html',
|
|
12
|
+
use: {
|
|
13
|
+
baseURL: `http://localhost:${E2E_PORT}`,
|
|
14
|
+
trace: 'on-first-retry',
|
|
15
|
+
},
|
|
16
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
17
|
+
webServer: {
|
|
18
|
+
// Serve built dist/ with a static server so e2e works in CI without an SF org
|
|
19
|
+
// (ng serve runs the SF plugin/proxy middleware and can fail without an org).
|
|
20
|
+
command: `npx serve dist -l ${E2E_PORT}`,
|
|
21
|
+
url: `http://localhost:${E2E_PORT}`,
|
|
22
|
+
reuseExistingServer: !process.env.CI,
|
|
23
|
+
timeout: process.env.CI ? 120_000 : 60_000,
|
|
24
|
+
},
|
|
25
|
+
});
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/public/favicon.ico
ADDED
|
Binary file
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downloads the full GraphQL schema from a connected Salesforce org via introspection.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* npm run graphql:schema
|
|
6
|
+
* node scripts/get-graphql-schema.mjs [output-path]
|
|
7
|
+
*
|
|
8
|
+
* The default output path matches the schema location expected by codegen.yml
|
|
9
|
+
* and .graphqlrc.yml so that codegen and IDE tooling resolve it automatically.
|
|
10
|
+
*/
|
|
11
|
+
import { writeFileSync } from 'node:fs';
|
|
12
|
+
import { resolve } from 'node:path';
|
|
13
|
+
import { getOrgInfo } from '@salesforce/ui-bundle/app';
|
|
14
|
+
import { buildClientSchema, getIntrospectionQuery, printSchema } from 'graphql';
|
|
15
|
+
import { pruneSchema } from '@graphql-tools/utils';
|
|
16
|
+
|
|
17
|
+
const DEFAULT_SCHEMA_PATH = '../../../../../schema.graphql';
|
|
18
|
+
const TARGET_ORG = process.env.SF_TARGET_ORG || undefined;
|
|
19
|
+
|
|
20
|
+
async function executeSalesforceGraphQLQuery(query, variables, operationName) {
|
|
21
|
+
const orgInfo = await getOrgInfo(TARGET_ORG);
|
|
22
|
+
if (!orgInfo) {
|
|
23
|
+
throw new Error('Could not resolve a Salesforce org. Set SF_TARGET_ORG or a default org.');
|
|
24
|
+
}
|
|
25
|
+
const { rawInstanceUrl: instanceUrl, apiVersion, accessToken } = orgInfo;
|
|
26
|
+
|
|
27
|
+
const targetUrl = `${instanceUrl}/services/data/v${apiVersion}/graphql`;
|
|
28
|
+
|
|
29
|
+
console.log(`Executing introspection query against ${targetUrl}`);
|
|
30
|
+
const response = await fetch(targetUrl, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${accessToken}`,
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
'X-Chatter-Entity-Encoding': 'false',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({ query, variables, operationName }),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
const errorText = await response.text();
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Salesforce GraphQL request failed: ${response.status} ${response.statusText} - ${errorText}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const outputPath = resolve(process.argv[2] || DEFAULT_SCHEMA_PATH);
|
|
52
|
+
|
|
53
|
+
const introspectionResult = await executeSalesforceGraphQLQuery(
|
|
54
|
+
getIntrospectionQuery(),
|
|
55
|
+
{},
|
|
56
|
+
'IntrospectionQuery',
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const schema = buildClientSchema(introspectionResult.data);
|
|
60
|
+
const prunedSchema = pruneSchema(schema);
|
|
61
|
+
const sdl = printSchema(prunedSchema);
|
|
62
|
+
|
|
63
|
+
writeFileSync(outputPath, sdl);
|
|
64
|
+
|
|
65
|
+
console.log(`Schema saved to ${outputPath}`);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('Error:', error.message);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepares dist/ for e2e: root-relative asset paths + SPA fallback for serve.
|
|
3
|
+
*
|
|
4
|
+
* angular.json sets deployUrl: "./", so the built index.html references
|
|
5
|
+
* scripts/styles with a relative "./" prefix (e.g. ./main-HASH.js). When the
|
|
6
|
+
* SPA fallback serves index.html for a deep route like /non-existent-route,
|
|
7
|
+
* those "./" paths resolve against the wrong base and 404, so the app never
|
|
8
|
+
* boots. Rewrite them to root-relative "/" paths.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { join, dirname } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
// angular.json outputPath: { base: "dist", browser: "" } -> files land in dist/
|
|
16
|
+
const distDir = join(__dirname, '..', 'dist');
|
|
17
|
+
|
|
18
|
+
// Rewrite index.html so asset paths are root-relative (./main-x.js -> /main-x.js)
|
|
19
|
+
const indexPath = join(distDir, 'index.html');
|
|
20
|
+
let html = readFileSync(indexPath, 'utf8');
|
|
21
|
+
html = html.replace(/(src|href)="\.\//g, '$1="/');
|
|
22
|
+
writeFileSync(indexPath, html);
|
|
23
|
+
|
|
24
|
+
// SPA fallback so /non-existent-route etc. serve index.html
|
|
25
|
+
writeFileSync(
|
|
26
|
+
join(distDir, 'serve.json'),
|
|
27
|
+
JSON.stringify({
|
|
28
|
+
rewrites: [{ source: '**', destination: '/index.html' }],
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
import { DataClient } from './data-client.service';
|
|
3
|
+
import { createDataSDK } from '@salesforce/platform-sdk';
|
|
4
|
+
|
|
5
|
+
vi.mock('@salesforce/platform-sdk', () => ({
|
|
6
|
+
createDataSDK: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe('DataClient', () => {
|
|
10
|
+
let service: DataClient;
|
|
11
|
+
let mockGraphqlQuery: ReturnType<typeof vi.fn>;
|
|
12
|
+
let mockGraphqlMutate: ReturnType<typeof vi.fn>;
|
|
13
|
+
let mockFetch: ReturnType<typeof vi.fn>;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
mockGraphqlQuery = vi.fn();
|
|
17
|
+
mockGraphqlMutate = vi.fn();
|
|
18
|
+
mockFetch = vi.fn();
|
|
19
|
+
|
|
20
|
+
vi.mocked(createDataSDK).mockResolvedValue({
|
|
21
|
+
graphql: {
|
|
22
|
+
query: mockGraphqlQuery,
|
|
23
|
+
mutate: mockGraphqlMutate,
|
|
24
|
+
},
|
|
25
|
+
fetch: mockFetch,
|
|
26
|
+
} as any);
|
|
27
|
+
|
|
28
|
+
await TestBed.configureTestingModule({
|
|
29
|
+
providers: [DataClient],
|
|
30
|
+
}).compileComponents();
|
|
31
|
+
|
|
32
|
+
service = TestBed.inject(DataClient);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
vi.clearAllMocks();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should create the service', () => {
|
|
40
|
+
expect(service).toBeTruthy();
|
|
41
|
+
expect(service).toBeInstanceOf(DataClient);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should route plain query operations to graphql.query and return result.data', async () => {
|
|
45
|
+
const operation = 'query { user { id name } }';
|
|
46
|
+
const expectedData = { user: { id: '123', name: 'Test User' } };
|
|
47
|
+
mockGraphqlQuery.mockResolvedValue({ data: expectedData });
|
|
48
|
+
|
|
49
|
+
const result = await service.execute(operation);
|
|
50
|
+
|
|
51
|
+
expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
|
|
52
|
+
expect(mockGraphqlMutate).not.toHaveBeenCalled();
|
|
53
|
+
expect(result).toEqual(expectedData);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should route anonymous query operations to graphql.query', async () => {
|
|
57
|
+
const operation = '{ user { id name } }';
|
|
58
|
+
const expectedData = { user: { id: '456', name: 'Anonymous User' } };
|
|
59
|
+
mockGraphqlQuery.mockResolvedValue({ data: expectedData });
|
|
60
|
+
|
|
61
|
+
const result = await service.execute(operation);
|
|
62
|
+
|
|
63
|
+
expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
|
|
64
|
+
expect(mockGraphqlMutate).not.toHaveBeenCalled();
|
|
65
|
+
expect(result).toEqual(expectedData);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should route mutation operations to graphql.mutate', async () => {
|
|
69
|
+
const operation = 'mutation { updateUser(id: "123", name: "New Name") { id name } }';
|
|
70
|
+
const expectedData = { updateUser: { id: '123', name: 'New Name' } };
|
|
71
|
+
mockGraphqlMutate.mockResolvedValue({ data: expectedData });
|
|
72
|
+
|
|
73
|
+
const result = await service.execute(operation);
|
|
74
|
+
|
|
75
|
+
expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables: undefined });
|
|
76
|
+
expect(mockGraphqlQuery).not.toHaveBeenCalled();
|
|
77
|
+
expect(result).toEqual(expectedData);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should detect mutation with leading GraphQL comment and route to graphql.mutate', async () => {
|
|
81
|
+
const operation = '# This is a comment\nmutation { deleteUser(id: "123") { success } }';
|
|
82
|
+
const expectedData = { deleteUser: { success: true } };
|
|
83
|
+
mockGraphqlMutate.mockResolvedValue({ data: expectedData });
|
|
84
|
+
|
|
85
|
+
const result = await service.execute(operation);
|
|
86
|
+
|
|
87
|
+
expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables: undefined });
|
|
88
|
+
expect(mockGraphqlQuery).not.toHaveBeenCalled();
|
|
89
|
+
expect(result).toEqual(expectedData);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should not treat query as mutation when comment contains "mutation" word', async () => {
|
|
93
|
+
const operation = '# this is not a mutation, just a query\nquery { user { id } }';
|
|
94
|
+
const expectedData = { user: { id: '789' } };
|
|
95
|
+
mockGraphqlQuery.mockResolvedValue({ data: expectedData });
|
|
96
|
+
|
|
97
|
+
const result = await service.execute(operation);
|
|
98
|
+
|
|
99
|
+
expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
|
|
100
|
+
expect(mockGraphqlMutate).not.toHaveBeenCalled();
|
|
101
|
+
expect(result).toEqual(expectedData);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should throw error when result.errors contains errors', async () => {
|
|
105
|
+
const operation = 'query { user { id } }';
|
|
106
|
+
mockGraphqlQuery.mockResolvedValue({
|
|
107
|
+
data: null,
|
|
108
|
+
errors: [{ message: 'Field not found' }, { message: 'Permission denied' }],
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await expect(service.execute(operation)).rejects.toThrow(
|
|
112
|
+
'GraphQL Error: Field not found; Permission denied',
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should throw error when result.errors contains a single error', async () => {
|
|
117
|
+
const operation = 'query { user { id } }';
|
|
118
|
+
mockGraphqlQuery.mockResolvedValue({
|
|
119
|
+
data: null,
|
|
120
|
+
errors: [{ message: 'Unauthorized' }],
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
await expect(service.execute(operation)).rejects.toThrow('GraphQL Error: Unauthorized');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should throw error when result.data is null with no errors', async () => {
|
|
127
|
+
const operation = 'query { user { id } }';
|
|
128
|
+
mockGraphqlQuery.mockResolvedValue({ data: null });
|
|
129
|
+
|
|
130
|
+
await expect(service.execute(operation)).rejects.toThrow('GraphQL response data is null');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should pass variables through to graphql.query', async () => {
|
|
134
|
+
const operation = 'query GetUser($id: ID!) { user(id: $id) { id name } }';
|
|
135
|
+
const variables = { id: '999' };
|
|
136
|
+
const expectedData = { user: { id: '999', name: 'Variable User' } };
|
|
137
|
+
mockGraphqlQuery.mockResolvedValue({ data: expectedData });
|
|
138
|
+
|
|
139
|
+
const result = await service.execute(operation, variables);
|
|
140
|
+
|
|
141
|
+
expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables });
|
|
142
|
+
expect(result).toEqual(expectedData);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should pass variables through to graphql.mutate', async () => {
|
|
146
|
+
const operation =
|
|
147
|
+
'mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } }';
|
|
148
|
+
const variables = { id: '888', name: 'Updated Name' };
|
|
149
|
+
const expectedData = { updateUser: { id: '888', name: 'Updated Name' } };
|
|
150
|
+
mockGraphqlMutate.mockResolvedValue({ data: expectedData });
|
|
151
|
+
|
|
152
|
+
const result = await service.execute(operation, variables);
|
|
153
|
+
|
|
154
|
+
expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables });
|
|
155
|
+
expect(result).toEqual(expectedData);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should proxy fetch to sdk.fetch and return the raw Response', async () => {
|
|
159
|
+
const url = '/services/apexrest/auth/login';
|
|
160
|
+
const init: RequestInit = {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
body: JSON.stringify({ email: 'a@b.com' }),
|
|
163
|
+
headers: { 'Content-Type': 'application/json' },
|
|
164
|
+
};
|
|
165
|
+
const expectedResponse = { ok: true, status: 200 } as Response;
|
|
166
|
+
mockFetch.mockResolvedValue(expectedResponse);
|
|
167
|
+
|
|
168
|
+
const response = await service.fetch(url, init);
|
|
169
|
+
|
|
170
|
+
expect(mockFetch).toHaveBeenCalledWith(url, init);
|
|
171
|
+
expect(response).toBe(expectedResponse);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should call fetch with no init when omitted', async () => {
|
|
175
|
+
const url = '/services/data/v64.0/chatter/users/me';
|
|
176
|
+
const expectedResponse = { ok: true, status: 200 } as Response;
|
|
177
|
+
mockFetch.mockResolvedValue(expectedResponse);
|
|
178
|
+
|
|
179
|
+
const response = await service.fetch(url);
|
|
180
|
+
|
|
181
|
+
expect(mockFetch).toHaveBeenCalledWith(url, undefined);
|
|
182
|
+
expect(response).toBe(expectedResponse);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { createDataSDK } from '@salesforce/platform-sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* True when the operation's first definition is a `mutation`. Strips GraphQL
|
|
6
|
+
* comments first so a leading `# ...` line can't mask the keyword. Queries
|
|
7
|
+
* (named or anonymous `{ ... }` shorthand) and subscriptions fall through to
|
|
8
|
+
* query().
|
|
9
|
+
*/
|
|
10
|
+
function isMutation(operation: string): boolean {
|
|
11
|
+
return /^\s*mutation\b/.test(operation.replace(/#[^\n\r]*/g, ''));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The single data-access client for the app — a thin wrapper over
|
|
16
|
+
* `createDataSDK` that centralizes both of the SDK's surfaces:
|
|
17
|
+
*
|
|
18
|
+
* - `execute()` for GraphQL (routes mutations to `sdk.graphql.mutate` and
|
|
19
|
+
* everything else to `sdk.graphql.query`, with centralized error handling).
|
|
20
|
+
* Use with gql-tagged queries and generated operation types for type-safe
|
|
21
|
+
* calls.
|
|
22
|
+
* - `fetch()` for REST (proxies `sdk.fetch`, returning the raw `Response` so
|
|
23
|
+
* callers keep full control over response parsing / error shaping).
|
|
24
|
+
*
|
|
25
|
+
* Consumers inject this instead of calling `createDataSDK` directly, so the SDK
|
|
26
|
+
* bootstrap lives in exactly one place. Feature packages consume it via an
|
|
27
|
+
* `__inherit__data-client.service` stub (base wins at compose).
|
|
28
|
+
*/
|
|
29
|
+
@Injectable({ providedIn: 'root' })
|
|
30
|
+
export class DataClient {
|
|
31
|
+
/**
|
|
32
|
+
* Executes a GraphQL operation and returns its `data`, throwing on GraphQL
|
|
33
|
+
* errors or a null payload.
|
|
34
|
+
*/
|
|
35
|
+
async execute<TData, TVariables = Record<string, unknown>>(
|
|
36
|
+
operation: string,
|
|
37
|
+
variables?: TVariables,
|
|
38
|
+
): Promise<TData> {
|
|
39
|
+
const data = await createDataSDK();
|
|
40
|
+
const result = isMutation(operation)
|
|
41
|
+
? await data.graphql!.mutate<TData, TVariables>({
|
|
42
|
+
mutation: operation,
|
|
43
|
+
variables,
|
|
44
|
+
})
|
|
45
|
+
: await data.graphql!.query<TData, TVariables>({
|
|
46
|
+
query: operation,
|
|
47
|
+
variables,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (result.errors?.length) {
|
|
51
|
+
const msg = result.errors.map((e) => e.message).join('; ');
|
|
52
|
+
throw new Error(`GraphQL Error: ${msg}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (result.data == null) {
|
|
56
|
+
throw new Error('GraphQL response data is null');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return result.data;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Performs a REST request through the SDK's authenticated `fetch`, returning
|
|
64
|
+
* the raw `Response`. Callers parse the body / shape errors themselves (e.g.
|
|
65
|
+
* via `handleApiResponse`).
|
|
66
|
+
*
|
|
67
|
+
* @param input - The request URL (e.g. an Apex REST route).
|
|
68
|
+
* @param init - Standard `fetch` options (method, headers, body, …).
|
|
69
|
+
*/
|
|
70
|
+
async fetch(input: string, init?: RequestInit): Promise<Response> {
|
|
71
|
+
const sdk = await createDataSDK();
|
|
72
|
+
return sdk.fetch!(input, init);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
|
|
7
|
+
import { provideRouter } from '@angular/router';
|
|
8
|
+
import { provideNativeDateAdapter as provideBrnNativeDateAdapter } from '@spartan-ng/brain/date-time';
|
|
9
|
+
import { provideNgIconsConfig } from '@ng-icons/core';
|
|
10
|
+
|
|
11
|
+
import { routes } from './app.routes';
|
|
12
|
+
|
|
13
|
+
export const appConfig: ApplicationConfig = {
|
|
14
|
+
providers: [
|
|
15
|
+
provideBrowserGlobalErrorListeners(),
|
|
16
|
+
provideRouter(routes),
|
|
17
|
+
provideBrnNativeDateAdapter(),
|
|
18
|
+
provideNgIconsConfig({ size: '1rem' }),
|
|
19
|
+
],
|
|
20
|
+
};
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.html
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<router-outlet />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { Routes } from '@angular/router';
|
|
7
|
+
import { AppLayoutComponent } from './components/layout/app-layout/app-layout';
|
|
8
|
+
import { HomeComponent } from './pages/home/home';
|
|
9
|
+
import { NotFoundComponent } from './pages/not-found/not-found';
|
|
10
|
+
|
|
11
|
+
export const routes: Routes = [
|
|
12
|
+
{
|
|
13
|
+
path: '',
|
|
14
|
+
component: AppLayoutComponent,
|
|
15
|
+
children: [
|
|
16
|
+
{
|
|
17
|
+
path: '',
|
|
18
|
+
component: HomeComponent,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
path: '**',
|
|
22
|
+
component: NotFoundComponent,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
];
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.spec.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
import { provideRouter } from '@angular/router';
|
|
3
|
+
import { App } from './app';
|
|
4
|
+
|
|
5
|
+
describe('App', () => {
|
|
6
|
+
beforeEach(async () => {
|
|
7
|
+
await TestBed.configureTestingModule({
|
|
8
|
+
imports: [App],
|
|
9
|
+
providers: [provideRouter([])],
|
|
10
|
+
}).compileComponents();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should create the app', () => {
|
|
14
|
+
const fixture = TestBed.createComponent(App);
|
|
15
|
+
const app = fixture.componentInstance;
|
|
16
|
+
expect(app).toBeTruthy();
|
|
17
|
+
});
|
|
18
|
+
});
|
package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
7
|
+
import { RouterOutlet } from '@angular/router';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'app-root',
|
|
11
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
12
|
+
imports: [RouterOutlet],
|
|
13
|
+
templateUrl: './app.html',
|
|
14
|
+
})
|
|
15
|
+
export class App {}
|