@koobiq/components 21.0.0 → 21.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/badge/_badge-theme.scss +31 -0
- package/breadcrumbs/breadcrumbs.scss +5 -1
- package/checkbox/_checkbox-theme.scss +0 -17
- package/checkbox/checkbox-tokens.scss +0 -4
- package/code-block/_code-block-theme.scss +7 -6
- package/code-block/code-block-tokens.scss +8 -4
- package/code-block/code-block.scss +54 -32
- package/content-panel/content-panel-header.scss +2 -3
- package/content-panel/content-panel.scss +3 -0
- package/core/selection/pseudo-checkbox/pseudo-checkbox-tokens.scss +0 -2
- package/fesm2022/koobiq-components-accordion.mjs +4 -4
- package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
- package/fesm2022/koobiq-components-actions-panel.mjs +10 -2
- package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-app-switcher.mjs +1 -1
- package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
- package/fesm2022/koobiq-components-badge.mjs +2 -2
- package/fesm2022/koobiq-components-badge.mjs.map +1 -1
- package/fesm2022/koobiq-components-breadcrumbs.mjs +2 -2
- package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-checkbox.mjs +18 -8
- package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
- package/fesm2022/koobiq-components-clamped-text.mjs +78 -10
- package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
- package/fesm2022/koobiq-components-code-block.mjs +106 -394
- package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
- package/fesm2022/koobiq-components-content-panel.mjs +4 -4
- package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-core.mjs +300 -37
- package/fesm2022/koobiq-components-core.mjs.map +1 -1
- package/fesm2022/koobiq-components-datepicker.mjs +151 -60
- package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-divider.mjs +3 -3
- package/fesm2022/koobiq-components-divider.mjs.map +1 -1
- package/fesm2022/koobiq-components-dropdown.mjs +3 -3
- package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-file-upload.mjs +17 -8
- package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
- package/fesm2022/koobiq-components-filter-bar.mjs +124 -41
- package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-flag.mjs +3 -3
- package/fesm2022/koobiq-components-flag.mjs.map +1 -1
- package/fesm2022/koobiq-components-form-field.mjs +90 -27
- package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
- package/fesm2022/koobiq-components-icon.mjs +38 -17
- package/fesm2022/koobiq-components-icon.mjs.map +1 -1
- package/fesm2022/koobiq-components-inline-edit.mjs +19 -2
- package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
- package/fesm2022/koobiq-components-input.mjs +76 -17
- package/fesm2022/koobiq-components-input.mjs.map +1 -1
- package/fesm2022/koobiq-components-list.mjs +1 -1
- package/fesm2022/koobiq-components-list.mjs.map +1 -1
- package/fesm2022/koobiq-components-modal.mjs +3 -3
- package/fesm2022/koobiq-components-modal.mjs.map +1 -1
- package/fesm2022/koobiq-components-navbar.mjs +86 -25
- package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
- package/fesm2022/koobiq-components-notification-center.mjs +4 -4
- package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-overflow-items.mjs +116 -38
- package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
- package/fesm2022/koobiq-components-popover.mjs +86 -7
- package/fesm2022/koobiq-components-popover.mjs.map +1 -1
- package/fesm2022/koobiq-components-radio.mjs +41 -19
- package/fesm2022/koobiq-components-radio.mjs.map +1 -1
- package/fesm2022/koobiq-components-search-expandable.mjs +29 -17
- package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
- package/fesm2022/koobiq-components-select.mjs +49 -12
- package/fesm2022/koobiq-components-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidepanel.mjs +198 -186
- package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
- package/fesm2022/koobiq-components-splitter.mjs +49 -25
- package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
- package/fesm2022/koobiq-components-tabs.mjs +30 -11
- package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
- package/fesm2022/koobiq-components-tags.mjs +1 -1
- package/fesm2022/koobiq-components-tags.mjs.map +1 -1
- package/fesm2022/koobiq-components-textarea.mjs +28 -11
- package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
- package/fesm2022/koobiq-components-time-range.mjs +2 -2
- package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
- package/fesm2022/koobiq-components-timepicker.mjs +71 -16
- package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-timezone.mjs +2 -2
- package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
- package/fesm2022/koobiq-components-toast.mjs +2 -2
- package/fesm2022/koobiq-components-toast.mjs.map +1 -1
- package/fesm2022/koobiq-components-toggle.mjs +25 -9
- package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-tooltip.mjs +90 -17
- package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
- package/fesm2022/koobiq-components-top-bar.mjs +27 -7
- package/fesm2022/koobiq-components-top-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree-select.mjs +24 -9
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +288 -109
- package/fesm2022/koobiq-components-tree.mjs.map +1 -1
- package/file-upload/_file-upload-theme.scss +0 -12
- package/file-upload/file-upload-tokens.scss +0 -1
- package/file-upload/file-upload.scss +0 -1
- package/filter-bar/_filter-bar-theme.scss +7 -8
- package/filter-bar/filter-bar.scss +0 -1
- package/filter-bar/pipes/base-pipe.scss +36 -2
- package/filter-bar/pipes/pipe-multi-tree-select.scss +27 -0
- package/form-field/_fieldset-theme.scss +2 -7
- package/form-field/_form-field-theme.scss +9 -22
- package/form-field/_hint-theme.scss +20 -0
- package/form-field/fieldset-tokens.scss +0 -1
- package/form-field/fieldset.scss +0 -3
- package/form-field/form-field-tokens.scss +1 -1
- package/form-field/form-field.scss +9 -0
- package/form-field/hint-tokens.scss +3 -0
- package/modal/modal.scss +2 -0
- package/navbar/_navbar-item_vertical.scss +48 -2
- package/navbar/_navbar-theme.scss +11 -3
- package/navbar/navbar-item.scss +17 -0
- package/navbar/navbar-tokens.scss +3 -0
- package/package.json +4 -4
- package/popover/popover.scss +1 -1
- package/radio/_radio-theme.scss +0 -30
- package/radio/radio-tokens.scss +0 -2
- package/schematics/collection.json +94 -89
- package/schematics/migrations/accordion-state-saving-default/{index.js → index.cjs} +5 -4
- package/schematics/migrations/actions-panel-overlay-container/{index.js → index.cjs} +5 -4
- package/schematics/migrations/alert-signals/{index.js → index.cjs} +14 -13
- package/schematics/migrations/angular-animations-removal/index.cjs +21 -0
- package/schematics/migrations/app-switcher-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/autocomplete-panel-width-auto/{index.js → index.cjs} +6 -5
- package/schematics/migrations/autocomplete-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/badge-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/button-state-and-styles/{index.js → index.cjs} +7 -6
- package/schematics/migrations/button-supported-colors/{index.js → index.cjs} +7 -6
- package/schematics/migrations/button-toggle-signals-and-aria/{index.js → index.cjs} +7 -6
- package/schematics/migrations/button-truncation/{index.js → index.cjs} +7 -6
- package/schematics/migrations/checkbox-signals/{index.js → index.cjs} +9 -8
- package/schematics/migrations/clamped-text-disclosure/{index.js → index.cjs} +5 -4
- package/schematics/migrations/code-block-highlight-js-core/README.md +53 -0
- package/schematics/migrations/code-block-highlight-js-core/data.cjs +64 -0
- package/schematics/migrations/code-block-highlight-js-core/index.cjs +319 -0
- package/schematics/migrations/code-block-highlight-js-core/schema.json +20 -0
- package/schematics/migrations/code-block-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/color-signals/index.cjs +20 -0
- package/schematics/migrations/core-mixins-removal/index.cjs +18 -0
- package/schematics/migrations/css-selectors/{index.js → index.cjs} +4 -3
- package/schematics/migrations/datepicker-signals/index.cjs +18 -0
- package/schematics/migrations/deprecated-icons/README.md +21 -5
- package/schematics/migrations/deprecated-icons/{index.js → index.cjs} +15 -28
- package/schematics/migrations/deprecated-icons/schema.json +1 -1
- package/schematics/migrations/design-tokens-v4/{index.js → index.cjs} +3 -2
- package/schematics/migrations/divider-signals-and-aria/{index.js → index.cjs} +5 -4
- package/schematics/migrations/dl-attribute-coercion/{index.js → index.cjs} +7 -6
- package/schematics/migrations/dl-standalone-names/{index.js → index.cjs} +11 -10
- package/schematics/migrations/dropdown-demote-overlay/{index.js → index.cjs} +7 -6
- package/schematics/migrations/dropdown-signals/index.cjs +20 -0
- package/schematics/migrations/empty-state-error-color/{index.js → index.cjs} +5 -4
- package/schematics/migrations/empty-state-size-attr/{index.js → index.cjs} +6 -5
- package/schematics/migrations/file-upload-cva-and-primitives/{index.js → index.cjs} +5 -4
- package/schematics/migrations/file-upload-deprecated-outputs/{index.js → index.cjs} +5 -4
- package/schematics/migrations/filter-bar-rename-action/{index.js → index.cjs} +5 -4
- package/schematics/migrations/filter-bar-signals/{index.js → index.cjs} +16 -15
- package/schematics/migrations/filter-bar-state-saving-default/{index.js → index.cjs} +5 -4
- package/schematics/migrations/flag-inner-html/{index.js → index.cjs} +5 -4
- package/schematics/migrations/form-field-signals/{index.js → index.cjs} +18 -17
- package/schematics/migrations/icon-semantics-and-api/{data.js → data.cjs} +4 -4
- package/schematics/migrations/icon-semantics-and-api/{index.js → index.cjs} +6 -5
- package/schematics/migrations/icons-replacement/README.md +16 -2
- package/schematics/migrations/icons-replacement/{index.js → index.cjs} +21 -18
- package/schematics/migrations/icons-replacement/schema.json +12 -3
- package/schematics/migrations/inline-edit-a11y-and-types/{index.js → index.cjs} +5 -4
- package/schematics/migrations/input-number-surface/{index.js → index.cjs} +5 -4
- package/schematics/migrations/input-signals/index.cjs +18 -0
- package/schematics/migrations/link-deprecated-path/{index.js → index.cjs} +4 -3
- package/schematics/migrations/link-signals/{index.js → index.cjs} +5 -4
- package/schematics/migrations/list-signals/index.cjs +18 -0
- package/schematics/migrations/list-tree-multiple-input/{index.js → index.cjs} +7 -6
- package/schematics/migrations/loader-overlay-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/loader-overlay-size-attr/{index.js → index.cjs} +6 -5
- package/schematics/migrations/locale-configuration-providers/{index.js → index.cjs} +5 -4
- package/schematics/migrations/mandatory-peer-dependencies/{index.js → index.cjs} +3 -2
- package/schematics/migrations/markdown-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/modal-dialog-semantics/{index.js → index.cjs} +5 -4
- package/schematics/migrations/modal-signals/index.cjs +20 -0
- package/schematics/migrations/navbar-signals-and-aria/{index.js → index.cjs} +7 -6
- package/schematics/migrations/new-icons-pack/README.md +37 -25
- package/schematics/migrations/new-icons-pack/{index.js → index.cjs} +29 -38
- package/schematics/migrations/new-icons-pack/replacement.json +2 -14
- package/schematics/migrations/new-icons-pack/schema.json +3 -3
- package/schematics/migrations/notification-center-signals/{index.js → index.cjs} +5 -4
- package/schematics/migrations/option-signals/index.cjs +20 -0
- package/schematics/migrations/popover-leave-delay/{index.js → index.cjs} +5 -4
- package/schematics/migrations/progress-bar-percentage-and-aria/{index.js → index.cjs} +5 -4
- package/schematics/migrations/progress-spinner-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/query-list-signals/index.cjs +18 -0
- package/schematics/migrations/radio-signals-and-aria/{index.js → index.cjs} +9 -8
- package/schematics/migrations/read-state-dwell-handlers/{index.js → index.cjs} +5 -4
- package/schematics/migrations/scrollbar-deprecated-path/{index.js → index.cjs} +4 -3
- package/schematics/migrations/select-signal-inputs/{index.js → index.cjs} +5 -4
- package/schematics/migrations/sidepanel-non-modal-behavior/{index.js → index.cjs} +5 -4
- package/schematics/migrations/signal-inputs-subclasses/index.cjs +18 -0
- package/schematics/migrations/split-button-optional-disabled/{index.js → index.cjs} +5 -4
- package/schematics/migrations/splitter-deprecated-path/{index.js → index.cjs} +4 -3
- package/schematics/migrations/state-saving-default/{index.js → index.cjs} +5 -4
- package/schematics/migrations/table-cell-content/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tabs-signals-and-aria/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tag-list-cleaner/{index.js → index.cjs} +7 -6
- package/schematics/migrations/tag-slots/{index.js → index.cjs} +6 -5
- package/schematics/migrations/tags-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/textarea-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/time-range-title-for/{index.js → index.cjs} +5 -4
- package/schematics/migrations/timepicker-signals/{index.js → index.cjs} +7 -6
- package/schematics/migrations/timezone-grouping-utils/{index.js → index.cjs} +5 -4
- package/schematics/migrations/title-encapsulation/{index.js → index.cjs} +5 -4
- package/schematics/migrations/toast-stack-and-defaults/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tooltip-pointer-events-and-types/{index.js → index.cjs} +5 -4
- package/schematics/migrations/top-bar-container-selectors/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tree-select-signals/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tree-signals/{index.js → index.cjs} +5 -4
- package/schematics/migrations/tree-state-saving-default/{index.js → index.cjs} +5 -4
- package/schematics/migrations/username-pipe-injection/{index.js → index.cjs} +5 -4
- package/schematics/migrations/v20-upgrade/{data.js → data.cjs} +7 -7
- package/schematics/migrations/v20-upgrade/index.cjs +19 -0
- package/schematics/migrations/v21-upgrade/{data.js → data.cjs} +22 -22
- package/schematics/migrations/v21-upgrade/{index.js → index.cjs} +11 -10
- package/schematics/migrations/zoneless-change-detection/index.cjs +21 -0
- package/schematics/migrations.json +87 -82
- package/schematics/ng-add/{index.js → index.cjs} +15 -289
- package/schematics/utils/{angular-parsing.js → angular-parsing.cjs} +2 -2
- package/schematics/utils/custom-data.cjs +64 -0
- package/schematics/utils/{deprecated-path-migration.js → deprecated-path-migration.cjs} +4 -3
- package/schematics/utils/html-config.cjs +148 -0
- package/schematics/utils/{icon-migration.js → icon-migration.cjs} +11 -5
- package/schematics/utils/list-item-pattern.cjs +16 -0
- package/schematics/utils/{messages.js → messages.cjs} +4 -0
- package/schematics/utils/package-config.cjs +99 -0
- package/schematics/utils/project-files.cjs +25 -0
- package/schematics/utils/replacement-driver.cjs +337 -0
- package/schematics/utils/safe-rule.cjs +23 -0
- package/schematics/utils/signal-members-migration.cjs +779 -0
- package/schematics/utils/tag-patterns.cjs +21 -0
- package/schematics/utils/template-ref-access.cjs +155 -0
- package/schematics/utils/{typescript.js → typescript.cjs} +1 -1
- package/schematics/utils/warn-only-migration.cjs +52 -0
- package/schematics/utils/workspace-styles.cjs +123 -0
- package/select/select.scss +7 -0
- package/tabs/_tabs-common.scss +23 -0
- package/textarea/textarea-tokens.scss +4 -1
- package/toast/toast.component.scss +1 -0
- package/toggle/_toggle-theme.scss +0 -17
- package/tooltip/tooltip.scss +1 -1
- package/top-bar/top-bar-tokens.scss +1 -0
- package/top-bar/top-bar.scss +10 -0
- package/types/koobiq-components-accordion.d.ts +25 -0
- package/types/koobiq-components-button-toggle.d.ts +6 -0
- package/types/koobiq-components-checkbox.d.ts +30 -0
- package/types/koobiq-components-clamped-text.d.ts +16 -3
- package/types/koobiq-components-code-block.d.ts +55 -14
- package/types/koobiq-components-core.d.ts +226 -13
- package/types/koobiq-components-datepicker.d.ts +28 -1
- package/types/koobiq-components-divider.d.ts +28 -10
- package/types/koobiq-components-dropdown.d.ts +19 -0
- package/types/koobiq-components-filter-bar.d.ts +79 -6
- package/types/koobiq-components-flag.d.ts +18 -0
- package/types/koobiq-components-form-field.d.ts +87 -6
- package/types/koobiq-components-icon.d.ts +15 -0
- package/types/koobiq-components-inline-edit.d.ts +8 -1
- package/types/koobiq-components-input.d.ts +22 -3
- package/types/koobiq-components-list.d.ts +6 -0
- package/types/koobiq-components-modal.d.ts +7 -0
- package/types/koobiq-components-navbar.d.ts +71 -7
- package/types/koobiq-components-notification-center.d.ts +13 -0
- package/types/koobiq-components-overflow-items.d.ts +26 -2
- package/types/koobiq-components-popover.d.ts +38 -3
- package/types/koobiq-components-radio.d.ts +30 -0
- package/types/koobiq-components-search-expandable.d.ts +10 -0
- package/types/koobiq-components-select.d.ts +36 -4
- package/types/koobiq-components-sidepanel.d.ts +52 -1
- package/types/koobiq-components-splitter.d.ts +13 -4
- package/types/koobiq-components-tabs.d.ts +4 -0
- package/types/koobiq-components-tags.d.ts +6 -0
- package/types/koobiq-components-textarea.d.ts +9 -2
- package/types/koobiq-components-timepicker.d.ts +15 -0
- package/types/koobiq-components-toggle.d.ts +30 -0
- package/types/koobiq-components-tooltip.d.ts +55 -10
- package/types/koobiq-components-top-bar.d.ts +11 -3
- package/types/koobiq-components-tree-select.d.ts +23 -8
- package/types/koobiq-components-tree.d.ts +144 -60
- package/schematics/migrations/angular-animations-removal/index.js +0 -20
- package/schematics/migrations/color-signals/index.js +0 -19
- package/schematics/migrations/core-mixins-removal/index.js +0 -17
- package/schematics/migrations/datepicker-signals/index.js +0 -17
- package/schematics/migrations/dropdown-signals/index.js +0 -19
- package/schematics/migrations/input-signals/index.js +0 -17
- package/schematics/migrations/list-signals/index.js +0 -17
- package/schematics/migrations/modal-signals/index.js +0 -19
- package/schematics/migrations/option-signals/index.js +0 -19
- package/schematics/migrations/query-list-signals/index.js +0 -17
- package/schematics/migrations/signal-inputs-subclasses/index.js +0 -17
- package/schematics/migrations/v20-upgrade/index.js +0 -18
- package/schematics/migrations/zoneless-change-detection/index.js +0 -20
- package/schematics/utils/package-config.js +0 -13
- /package/schematics/migrations/accordion-state-saving-default/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/actions-panel-overlay-container/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/alert-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/angular-animations-removal/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/app-switcher-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/autocomplete-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/badge-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/button-state-and-styles/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/button-supported-colors/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/button-toggle-signals-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/button-truncation/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/checkbox-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/clamped-text-disclosure/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/code-block-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/color-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/core-mixins-removal/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/css-selectors/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/datepicker-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/deprecated-icons/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/divider-signals-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/dl-attribute-coercion/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/dl-standalone-names/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/dropdown-demote-overlay/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/dropdown-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/empty-state-error-color/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/file-upload-cva-and-primitives/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/file-upload-deprecated-outputs/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/filter-bar-rename-action/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/filter-bar-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/filter-bar-state-saving-default/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/flag-inner-html/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/form-field-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/icons-replacement/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/inline-edit-a11y-and-types/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/input-number-surface/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/input-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/link-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/list-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/list-tree-multiple-input/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/loader-overlay-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/locale-configuration-providers/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/markdown-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/modal-dialog-semantics/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/modal-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/navbar-signals-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/new-icons-pack/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/notification-center-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/option-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/popover-leave-delay/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/progress-bar-percentage-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/progress-spinner-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/query-list-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/radio-signals-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/read-state-dwell-handlers/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/select-signal-inputs/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/sidepanel-non-modal-behavior/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/signal-inputs-subclasses/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/split-button-optional-disabled/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/state-saving-default/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/table-cell-content/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tabs-signals-and-aria/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tag-list-cleaner/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tags-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/textarea-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/time-range-title-for/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/timepicker-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/timezone-grouping-utils/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/title-encapsulation/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/toast-stack-and-defaults/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tooltip-pointer-events-and-types/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/top-bar-container-selectors/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tree-select-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tree-signals/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/tree-state-saving-default/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/username-pipe-injection/{data.js → data.cjs} +0 -0
- /package/schematics/migrations/zoneless-change-detection/{data.js → data.cjs} +0 -0
- /package/schematics/utils/{ast.js → ast.cjs} +0 -0
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
function noProject(project) {
|
|
4
4
|
return `Unable to find project '${project}' in the workspace`;
|
|
5
5
|
}
|
|
6
|
+
function noProjectOrDirectory(project) {
|
|
7
|
+
return `'${project}' is neither a project of the workspace nor a folder of it`;
|
|
8
|
+
}
|
|
6
9
|
const logMessage = (logger, content) => {
|
|
7
10
|
logger.warn('-------------------------');
|
|
8
11
|
logger.warn(content.join('\n'));
|
|
@@ -11,3 +14,4 @@ const logMessage = (logger, content) => {
|
|
|
11
14
|
|
|
12
15
|
exports.logMessage = logMessage;
|
|
13
16
|
exports.noProject = noProject;
|
|
17
|
+
exports.noProjectOrDirectory = noProjectOrDirectory;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var schematics = require('@angular-devkit/schematics');
|
|
4
|
+
var utility = require('@schematics/angular/utility');
|
|
5
|
+
var utils_messages = require('./messages.cjs');
|
|
6
|
+
var utils_projectFiles = require('./project-files.cjs');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sorts the keys of the given object.
|
|
10
|
+
* @returns A new object instance with sorted keys
|
|
11
|
+
*/
|
|
12
|
+
function sortObjectByKeys(obj) {
|
|
13
|
+
return Object.keys(obj)
|
|
14
|
+
.sort()
|
|
15
|
+
.reduce((result, key) => (result[key] = obj[key]) && result, {});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Adds a package to the package.json in the given tree
|
|
19
|
+
*/
|
|
20
|
+
function addPackageToPackageJson(tree, pkg, version, devDependency = false) {
|
|
21
|
+
if (tree.exists('package.json')) {
|
|
22
|
+
const sourceText = tree.read('package.json').toString('utf-8');
|
|
23
|
+
const json = JSON.parse(sourceText);
|
|
24
|
+
const dependenciesType = devDependency ? 'devDependencies' : 'dependencies';
|
|
25
|
+
const dependencies = json[dependenciesType] || {};
|
|
26
|
+
if (!dependencies[pkg]) {
|
|
27
|
+
dependencies[pkg] = version;
|
|
28
|
+
json[dependenciesType] = sortObjectByKeys(dependencies);
|
|
29
|
+
}
|
|
30
|
+
tree.overwrite('package.json', JSON.stringify(json, null, 2));
|
|
31
|
+
}
|
|
32
|
+
return tree;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets the version of the specified package by looking at the package.json in the given tree
|
|
36
|
+
*/
|
|
37
|
+
function getPackageVersionFromPackageJson(tree, name, includeDevDependencies = false) {
|
|
38
|
+
if (!tree.exists('package.json')) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const packageJson = JSON.parse(tree.read('package.json').toString('utf8'));
|
|
42
|
+
if (packageJson.dependencies && packageJson.dependencies[name]) {
|
|
43
|
+
return packageJson.dependencies[name];
|
|
44
|
+
}
|
|
45
|
+
if (includeDevDependencies && packageJson.devDependencies && packageJson.devDependencies[name]) {
|
|
46
|
+
return packageJson.devDependencies[name];
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
async function setupOptions(project, tree) {
|
|
51
|
+
if (project) {
|
|
52
|
+
const workspace = await utility.readWorkspace(tree);
|
|
53
|
+
const projectWorkspace = workspace.projects.get(project);
|
|
54
|
+
if (!projectWorkspace) {
|
|
55
|
+
throw new schematics.SchematicsException(utils_messages.noProject(project));
|
|
56
|
+
}
|
|
57
|
+
return projectWorkspace;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function resolveTargetDir(project, tree) {
|
|
61
|
+
if (!project) {
|
|
62
|
+
return tree.root;
|
|
63
|
+
}
|
|
64
|
+
const projectRoot = await utility.readWorkspace(tree).then((workspace) => workspace.projects.get(project)?.root, () => undefined);
|
|
65
|
+
if (projectRoot !== undefined) {
|
|
66
|
+
return tree.getDir(projectRoot || '/');
|
|
67
|
+
}
|
|
68
|
+
const folder = project
|
|
69
|
+
.replace(/\\/g, '/')
|
|
70
|
+
.replace(/^(\.\/)+/, '')
|
|
71
|
+
.replace(/\/+$/, '');
|
|
72
|
+
const dir = tree.getDir(folder || '/');
|
|
73
|
+
if (dir.subfiles.length || dir.subdirs.length) {
|
|
74
|
+
return dir;
|
|
75
|
+
}
|
|
76
|
+
throw new schematics.SchematicsException(utils_messages.noProjectOrDirectory(project));
|
|
77
|
+
}
|
|
78
|
+
async function getParsingInfo(project, tree) {
|
|
79
|
+
const tsPaths = new Set();
|
|
80
|
+
const templatePaths = new Set();
|
|
81
|
+
const projectDefinition = await setupOptions(project, tree);
|
|
82
|
+
// `ng update` passes no options at all, so without a project the whole workspace is migrated.
|
|
83
|
+
const root = projectDefinition?.root;
|
|
84
|
+
utils_projectFiles.visitProjectFiles(root ? tree.getDir(root) : tree.root, (filePath) => {
|
|
85
|
+
if (filePath.endsWith('.ts')) {
|
|
86
|
+
tsPaths.add(filePath);
|
|
87
|
+
}
|
|
88
|
+
if (filePath.endsWith('.html')) {
|
|
89
|
+
templatePaths.add(filePath);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return { tsPaths, templatePaths, projectDefinition };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
exports.addPackageToPackageJson = addPackageToPackageJson;
|
|
96
|
+
exports.getPackageVersionFromPackageJson = getPackageVersionFromPackageJson;
|
|
97
|
+
exports.getParsingInfo = getParsingInfo;
|
|
98
|
+
exports.resolveTargetDir = resolveTargetDir;
|
|
99
|
+
exports.setupOptions = setupOptions;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** Installed packages, build output, the Angular CLI cache and VCS metadata: never a consumer's source. */
|
|
4
|
+
const SKIPPED_DIRECTORIES = new Set(['node_modules', 'dist', '.angular', '.git']);
|
|
5
|
+
/**
|
|
6
|
+
* Calls `visitor` for every file under `dir`, in the order of `DirEntry.visit`, without descending into the
|
|
7
|
+
* skipped directories at any depth.
|
|
8
|
+
*
|
|
9
|
+
* `DirEntry.visit` lists the whole subtree before it visits anything, so a migration that filters its paths
|
|
10
|
+
* still stats every file of `node_modules` — under `ng update`, which runs over the workspace root, that is
|
|
11
|
+
* most of the run.
|
|
12
|
+
*/
|
|
13
|
+
function visitProjectFiles(dir, visitor) {
|
|
14
|
+
for (const name of dir.subfiles) {
|
|
15
|
+
const entry = dir.file(name);
|
|
16
|
+
if (entry)
|
|
17
|
+
visitor(entry.path, entry);
|
|
18
|
+
}
|
|
19
|
+
for (const name of dir.subdirs) {
|
|
20
|
+
if (!SKIPPED_DIRECTORIES.has(name))
|
|
21
|
+
visitProjectFiles(dir.dir(name), visitor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.visitProjectFiles = visitProjectFiles;
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils_listItemPattern = require('./list-item-pattern.cjs');
|
|
4
|
+
var utils_messages = require('./messages.cjs');
|
|
5
|
+
var utils_packageConfig = require('./package-config.cjs');
|
|
6
|
+
var utils_projectFiles = require('./project-files.cjs');
|
|
7
|
+
require('@angular-devkit/schematics');
|
|
8
|
+
require('@schematics/angular/utility');
|
|
9
|
+
|
|
10
|
+
/** A named import declaration: the `type` of a type-only one, its specifiers, its module. */
|
|
11
|
+
const NAMED_IMPORT = /\bimport\s*(type\s*)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;
|
|
12
|
+
/** An import specifier: an inline `type`, the imported name, its alias. */
|
|
13
|
+
const IMPORT_SPECIFIER = /^\s*(type\s+)?([\w$]+)(?:\s+as\s+([\w$]+))?\s*$/;
|
|
14
|
+
const COMMENT = /\/\/[^\n]*|\/\*[\s\S]*?\*\//g;
|
|
15
|
+
function compileReplacements(replacements) {
|
|
16
|
+
return replacements.map(({ from, unless, ...replacement }) => ({
|
|
17
|
+
...replacement,
|
|
18
|
+
from: new RegExp(from, 'g'),
|
|
19
|
+
unless: unless ? new RegExp(unless) : undefined
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Applies `replacements` to `content` in order, and collects the imports of those that changed it, which the file
|
|
24
|
+
* must gain or lose (e.g. `booleanAttribute` from `@angular/core` after a `toBoolean(` → `booleanAttribute(`
|
|
25
|
+
* rewrite).
|
|
26
|
+
*/
|
|
27
|
+
function applyReplacements(content, replacements) {
|
|
28
|
+
let result = content;
|
|
29
|
+
const importsToEnsure = [];
|
|
30
|
+
const importsToRemove = [];
|
|
31
|
+
for (const { from, to, unless, ensureImport, removeImport } of replacements) {
|
|
32
|
+
if (unless?.test(result))
|
|
33
|
+
continue;
|
|
34
|
+
const before = result;
|
|
35
|
+
result = result.replace(from, to);
|
|
36
|
+
if (result === before)
|
|
37
|
+
continue;
|
|
38
|
+
if (ensureImport)
|
|
39
|
+
importsToEnsure.push(ensureImport);
|
|
40
|
+
if (removeImport)
|
|
41
|
+
importsToRemove.push(removeImport);
|
|
42
|
+
}
|
|
43
|
+
return { content: result, changed: result !== content, importsToEnsure, importsToRemove };
|
|
44
|
+
}
|
|
45
|
+
/** The import specifiers that bind the name `local`: whether each is type-only, the name it imports, its module. */
|
|
46
|
+
function importBindings(content, local) {
|
|
47
|
+
return [...content.matchAll(NAMED_IMPORT)].flatMap(([, typeClause, specifiers, from]) => specifiers
|
|
48
|
+
.replace(COMMENT, '')
|
|
49
|
+
.split(',')
|
|
50
|
+
.flatMap((specifier) => {
|
|
51
|
+
const [, typeSpecifier, name, alias] = IMPORT_SPECIFIER.exec(specifier) ?? [];
|
|
52
|
+
return name && (alias ?? name) === local
|
|
53
|
+
? [{ typeOnly: !!(typeClause || typeSpecifier), name, from }]
|
|
54
|
+
: [];
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
/** Removes the type-only specifier of `symbol` from the named imports of `from`, and an import it empties. */
|
|
58
|
+
function removeTypeOnlyImport(content, symbol, from) {
|
|
59
|
+
const declaration = new RegExp(`(\\bimport\\s*(?:type\\s*)?)(\\{[^}]*\\})(\\s*from\\s*['"]${escapeRegExp(from)}['"];?[ \\t]*\\r?\\n?)`, 'g');
|
|
60
|
+
const specifier = new RegExp(utils_listItemPattern.listItemPattern(`\\b${symbol}\\b(?!\\s+as\\b)`));
|
|
61
|
+
return content.replace(declaration, (statement, open, clause, close) => {
|
|
62
|
+
const rest = clause.replace(specifier, '');
|
|
63
|
+
if (rest === clause)
|
|
64
|
+
return statement;
|
|
65
|
+
return /^\{\s*\}$/.test(rest) ? '' : `${open}${rest}${close}`;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Idempotently makes `symbol` of `from` a value import of a TypeScript source string, as the rewrites use it as a
|
|
70
|
+
* value. A value import of the name from any module, or an import of another symbol under the name, is left alone.
|
|
71
|
+
* A type-only import of it gives way to a value one: the symbol is added to the value import clause of `from`, or
|
|
72
|
+
* in a new import line at the top of the file (after any leading block / leading comments).
|
|
73
|
+
*/
|
|
74
|
+
function ensureImport(content, symbol, from) {
|
|
75
|
+
const bindings = importBindings(content, symbol);
|
|
76
|
+
// A second binding of the name would clash with it.
|
|
77
|
+
if (bindings.some((binding) => !binding.typeOnly || binding.name !== symbol || binding.from !== from)) {
|
|
78
|
+
return content;
|
|
79
|
+
}
|
|
80
|
+
// Under a type-only import, a value use of the symbol does not compile (TS1361).
|
|
81
|
+
if (bindings.length > 0)
|
|
82
|
+
content = removeTypeOnlyImport(content, symbol, from);
|
|
83
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
84
|
+
// Existing value import line from the same module — extend its clause.
|
|
85
|
+
const sameModule = new RegExp(`(\\bimport\\s*\\{)([^}]*)(\\}\\s*from\\s*['"]${escapeRegExp(from)}['"])`);
|
|
86
|
+
if (sameModule.test(content)) {
|
|
87
|
+
return content.replace(sameModule, (_match, open, body, close) => `${open}${appendSpecifier(body, symbol, eol)}${close}`);
|
|
88
|
+
}
|
|
89
|
+
// Otherwise, prepend a new import. Insert after any leading comment block
|
|
90
|
+
// / shebang. The simple heuristic finds the first non-comment, non-blank
|
|
91
|
+
// line and inserts right before it.
|
|
92
|
+
const newImport = `import { ${symbol} } from '${from}';`;
|
|
93
|
+
const lines = content.split(eol);
|
|
94
|
+
let insertAt = 0;
|
|
95
|
+
let inBlockComment = false;
|
|
96
|
+
for (let i = 0; i < lines.length; i++) {
|
|
97
|
+
const trimmed = lines[i].trim();
|
|
98
|
+
if (inBlockComment) {
|
|
99
|
+
if (trimmed.endsWith('*/'))
|
|
100
|
+
inBlockComment = false;
|
|
101
|
+
insertAt = i + 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (trimmed.startsWith('/*')) {
|
|
105
|
+
inBlockComment = !trimmed.includes('*/');
|
|
106
|
+
insertAt = i + 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (trimmed.startsWith('//') || trimmed.length === 0) {
|
|
110
|
+
insertAt = i + 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
lines.splice(insertAt, 0, newImport);
|
|
116
|
+
return lines.join(eol);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Appends `symbol` to `body`, the specifiers of a named import clause. After a line comment that ends the clause, it
|
|
120
|
+
* goes on a line of its own, ended by `eol`: on the line of the comment it would be commented out.
|
|
121
|
+
*/
|
|
122
|
+
function appendSpecifier(body, symbol, eol) {
|
|
123
|
+
const end = body.trimEnd();
|
|
124
|
+
// Where the last specifier ends, with the comments blanked out.
|
|
125
|
+
const split = end.replace(COMMENT, (comment) => ' '.repeat(comment.length)).trimEnd().length;
|
|
126
|
+
const [code, comments] = [end.slice(0, split), end.slice(split)];
|
|
127
|
+
const specifiers = `${code}${code && !code.endsWith(',') ? ',' : ''}${comments}`;
|
|
128
|
+
if (![...comments.matchAll(COMMENT)].pop()?.[0].startsWith('//'))
|
|
129
|
+
return `${specifiers} ${symbol} `;
|
|
130
|
+
const [indent] = /^[ \t]*/.exec(end.slice(end.lastIndexOf('\n') + 1));
|
|
131
|
+
return `${specifiers}${eol}${indent}${symbol}${body.slice(end.length)}`;
|
|
132
|
+
}
|
|
133
|
+
function escapeRegExp(s) {
|
|
134
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
135
|
+
}
|
|
136
|
+
/** The length of the match of the sticky `pattern` at `index` of `content`. */
|
|
137
|
+
function matchedLength(pattern, content, index) {
|
|
138
|
+
pattern.lastIndex = index;
|
|
139
|
+
return pattern.exec(content)?.[0].length ?? 0;
|
|
140
|
+
}
|
|
141
|
+
const INDENT = /[ \t]*/y;
|
|
142
|
+
const LINE_BREAK = /\r?\n/y;
|
|
143
|
+
const BLANK_LINES = /(?:[ \t]*\r?\n)*/y;
|
|
144
|
+
/**
|
|
145
|
+
* Idempotently strips `symbol` (under any alias) from the named imports of `from`, with one of its commas, and keeps
|
|
146
|
+
* the layout of the rest of the clause. An import it empties is dropped. A re-export of `from` is left to the
|
|
147
|
+
* rewrites, and dropped once they emptied it.
|
|
148
|
+
*
|
|
149
|
+
* A dropped statement takes its line with it, and the blank lines after it only when nothing but blank lines is
|
|
150
|
+
* above it: the file neither starts with a blank line nor gains two in a row.
|
|
151
|
+
*
|
|
152
|
+
* Cleans up after rewrites that delete or rename a symbol (e.g. `toBoolean(` → `booleanAttribute(` must also remove
|
|
153
|
+
* the import of `toBoolean`, which `@koobiq/components/core` no longer exports).
|
|
154
|
+
*/
|
|
155
|
+
function removeImport(content, symbol, from) {
|
|
156
|
+
const declaration = new RegExp(`\\b(import|export)(\\s*(?:type\\s*)?)(\\{[^}]*\\})(\\s*from\\s*['"]${escapeRegExp(from)}['"];?)`, 'g');
|
|
157
|
+
const specifier = new RegExp(utils_listItemPattern.listItemPattern(`(?<!\\bas\\s+)\\b${escapeRegExp(symbol)}\\b(?:\\s+as\\s+[\\w$]+)?`), 'g');
|
|
158
|
+
let result = '';
|
|
159
|
+
let end = 0;
|
|
160
|
+
for (const match of content.matchAll(declaration)) {
|
|
161
|
+
const [statement, keyword, modifier, clause, close] = match;
|
|
162
|
+
const rest = keyword === 'import' ? clause.replace(specifier, '') : clause;
|
|
163
|
+
result += content.slice(end, match.index);
|
|
164
|
+
end = match.index + statement.length;
|
|
165
|
+
if (!/^\{[\s,]*\}$/.test(rest.replace(COMMENT, ''))) {
|
|
166
|
+
result += rest === clause ? statement : `${keyword}${modifier}${rest}${close}`;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// The blanks around the statement go with it, and its line break when nothing else is on its line.
|
|
170
|
+
result = result.replace(/[ \t]*$/, '');
|
|
171
|
+
end += matchedLength(INDENT, content, end);
|
|
172
|
+
if (result && !result.endsWith('\n'))
|
|
173
|
+
continue;
|
|
174
|
+
const lineBreak = matchedLength(LINE_BREAK, content, end);
|
|
175
|
+
end += lineBreak;
|
|
176
|
+
if (lineBreak && (!result.trim() || /\n[ \t]*\r?\n$/.test(result))) {
|
|
177
|
+
end += matchedLength(BLANK_LINES, content, end);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return result + content.slice(end);
|
|
181
|
+
}
|
|
182
|
+
/** A named import or re-export: its keyword, an optional `type`, its specifiers in braces, its module. */
|
|
183
|
+
const NAMED_CLAUSE = /\b(import|export)(\s*(?:type\s*)?)(\{[^}]*\})(\s*from\s*['"][^'"]+['"])/g;
|
|
184
|
+
/**
|
|
185
|
+
* Drops each repeated specifier of a named import or re-export, which TypeScript rejects (TS2300): a rename makes
|
|
186
|
+
* one when the file imported the new name as well. Of the specifiers that import a name under the same local name,
|
|
187
|
+
* the first value one stays, or else the first one; the others go with one of their commas. A clause that stands in
|
|
188
|
+
* `original` as well, so the rewrites did not change it, is left alone.
|
|
189
|
+
*/
|
|
190
|
+
function dedupeImportSpecifiers(content, original = '') {
|
|
191
|
+
return content.replace(NAMED_CLAUSE, (statement, keyword, modifier, clause, rest) => {
|
|
192
|
+
if (original.includes(statement))
|
|
193
|
+
return statement;
|
|
194
|
+
const deduped = dedupeClause(clause);
|
|
195
|
+
return deduped === clause ? statement : `${keyword}${modifier}${deduped}${rest}`;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/** `clause`, the specifiers of a named import in braces, without the repeated ones. */
|
|
199
|
+
function dedupeClause(clause) {
|
|
200
|
+
// Blanked out, the comments neither split the clause nor read as specifiers.
|
|
201
|
+
const code = clause.replace(COMMENT, (comment) => ' '.repeat(comment.length));
|
|
202
|
+
const specifiers = [];
|
|
203
|
+
let comma = 0;
|
|
204
|
+
for (let index = 1; index < code.length; index++) {
|
|
205
|
+
if (code[index] !== ',' && index < code.length - 1)
|
|
206
|
+
continue;
|
|
207
|
+
const text = code.slice(comma + 1, index);
|
|
208
|
+
const [, typeSpecifier, name, alias] = IMPORT_SPECIFIER.exec(text) ?? [];
|
|
209
|
+
specifiers.push({
|
|
210
|
+
// The comma before it, or the opening brace of the first one.
|
|
211
|
+
comma,
|
|
212
|
+
start: comma + 1 + text.length - text.trimStart().length,
|
|
213
|
+
end: comma + 1 + text.trimEnd().length,
|
|
214
|
+
key: name ? `${name} as ${alias ?? name}` : null,
|
|
215
|
+
typeOnly: !!typeSpecifier
|
|
216
|
+
});
|
|
217
|
+
comma = index;
|
|
218
|
+
}
|
|
219
|
+
const kept = new Map();
|
|
220
|
+
specifiers.forEach(({ key, typeOnly }, index) => {
|
|
221
|
+
if (key === null)
|
|
222
|
+
return;
|
|
223
|
+
const first = kept.get(key);
|
|
224
|
+
if (first === undefined || (specifiers[first].typeOnly && !typeOnly))
|
|
225
|
+
kept.set(key, index);
|
|
226
|
+
});
|
|
227
|
+
const dropped = specifiers.map(({ key }, index) => key !== null && kept.get(key) !== index);
|
|
228
|
+
let result = clause;
|
|
229
|
+
// From the last, so that the positions of the others hold.
|
|
230
|
+
for (let index = specifiers.length - 1; index >= 0; index--) {
|
|
231
|
+
if (!dropped[index])
|
|
232
|
+
continue;
|
|
233
|
+
const { comma: before, start, end } = specifiers[index];
|
|
234
|
+
// With the comma before it after a specifier that stays, else with the comma after it.
|
|
235
|
+
const [from, to] = dropped.slice(0, index).includes(false)
|
|
236
|
+
? [before, end]
|
|
237
|
+
: [start, specifiers[index + 1].start];
|
|
238
|
+
result = result.slice(0, from) + result.slice(to);
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Builds the rule of a migration that rewrites the text of the project files: each `.ts`, `.html`, `.scss` and
|
|
244
|
+
* `.css` file is reported against the warn patterns, then rewritten with the replacements of its kind, and a `.ts`
|
|
245
|
+
* file loses the import specifiers the rewrites repeated and gains and loses the imports they call for. With `fix: false`, the files that would change are logged
|
|
246
|
+
* instead of written. `migrateOutsideFiles` runs after the walk; a file it changes counts in the summary.
|
|
247
|
+
*
|
|
248
|
+
* The patterns are compiled once per run rather than per file.
|
|
249
|
+
*/
|
|
250
|
+
function replacementMigrationRule(migration, options, migrateOutsideFiles) {
|
|
251
|
+
const { label } = migration;
|
|
252
|
+
const templateReplacements = compileReplacements(migration.templateReplacements);
|
|
253
|
+
const tsReplacements = [...compileReplacements(migration.tsReplacements), ...templateReplacements];
|
|
254
|
+
const scssReplacements = compileReplacements(migration.scssReplacements);
|
|
255
|
+
const warnPatterns = migration.warnPatterns.map(({ anchor, pattern, message }) => ({
|
|
256
|
+
anchor: anchor ? new RegExp(anchor) : null,
|
|
257
|
+
pattern: new RegExp(pattern),
|
|
258
|
+
message
|
|
259
|
+
}));
|
|
260
|
+
const pickReplacements = (filePath) => {
|
|
261
|
+
if (filePath.endsWith('.ts'))
|
|
262
|
+
return tsReplacements;
|
|
263
|
+
if (filePath.endsWith('.html'))
|
|
264
|
+
return templateReplacements;
|
|
265
|
+
if (filePath.endsWith('.scss') || filePath.endsWith('.css'))
|
|
266
|
+
return scssReplacements;
|
|
267
|
+
return null;
|
|
268
|
+
};
|
|
269
|
+
return async (tree, context) => {
|
|
270
|
+
// `ng update` invokes migrations with no options at all, and migrations.json declares no schema, so the
|
|
271
|
+
// schema default never reaches us — applying the fix is the intended behaviour there.
|
|
272
|
+
const fix = options.fix ?? true;
|
|
273
|
+
const projectDefinition = await utils_packageConfig.setupOptions(options.project, tree);
|
|
274
|
+
const root = projectDefinition?.root ?? '';
|
|
275
|
+
let touched = 0;
|
|
276
|
+
utils_projectFiles.visitProjectFiles(root ? tree.getDir(root) : tree.root, (filePath, entry) => {
|
|
277
|
+
const replacements = pickReplacements(filePath);
|
|
278
|
+
if (!replacements)
|
|
279
|
+
return;
|
|
280
|
+
const originalContent = entry.content.toString();
|
|
281
|
+
if (!originalContent)
|
|
282
|
+
return;
|
|
283
|
+
for (const { anchor, pattern, message } of warnPatterns) {
|
|
284
|
+
if (anchor && !anchor.test(originalContent))
|
|
285
|
+
continue;
|
|
286
|
+
if (pattern.test(originalContent))
|
|
287
|
+
utils_messages.logMessage(context.logger, [`${label} ${filePath}`, ` ${message}`]);
|
|
288
|
+
}
|
|
289
|
+
const result = applyReplacements(originalContent, replacements);
|
|
290
|
+
if (!result.changed)
|
|
291
|
+
return;
|
|
292
|
+
const content = filePath.endsWith('.ts') ? fixImports(result, originalContent) : result.content;
|
|
293
|
+
touched++;
|
|
294
|
+
if (fix) {
|
|
295
|
+
tree.overwrite(filePath, content);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
utils_messages.logMessage(context.logger, [`${label} would update ${filePath} (run with --fix to apply)`]);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
if (await migrateOutsideFiles?.(tree, context, fix))
|
|
302
|
+
touched++;
|
|
303
|
+
utils_messages.logMessage(context.logger, [
|
|
304
|
+
`${label} processed tree under "${root || '<workspace root>'}", ` +
|
|
305
|
+
`${fix ? 'updated' : 'would update'} ${touched} file(s).`
|
|
306
|
+
]);
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* The content of `result`, rewritten from `original`, with the specifiers the rewrites repeated dropped, then each of
|
|
311
|
+
* its imports removed, then ensured, once.
|
|
312
|
+
*/
|
|
313
|
+
function fixImports({ content, importsToEnsure, importsToRemove }, original) {
|
|
314
|
+
content = dedupeImportSpecifiers(content, original);
|
|
315
|
+
for (const { symbol, from } of unique(importsToRemove))
|
|
316
|
+
content = removeImport(content, symbol, from);
|
|
317
|
+
for (const { symbol, from } of unique(importsToEnsure))
|
|
318
|
+
content = ensureImport(content, symbol, from);
|
|
319
|
+
return content;
|
|
320
|
+
}
|
|
321
|
+
function unique(specifiers) {
|
|
322
|
+
const keys = new Set();
|
|
323
|
+
return specifiers.filter(({ symbol, from }) => {
|
|
324
|
+
const key = `${symbol}|${from}`;
|
|
325
|
+
if (keys.has(key))
|
|
326
|
+
return false;
|
|
327
|
+
keys.add(key);
|
|
328
|
+
return true;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
exports.applyReplacements = applyReplacements;
|
|
333
|
+
exports.compileReplacements = compileReplacements;
|
|
334
|
+
exports.dedupeImportSpecifiers = dedupeImportSpecifiers;
|
|
335
|
+
exports.ensureImport = ensureImport;
|
|
336
|
+
exports.removeImport = removeImport;
|
|
337
|
+
exports.replacementMigrationRule = replacementMigrationRule;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var schematics = require('@angular-devkit/schematics');
|
|
4
|
+
var rxjs = require('rxjs');
|
|
5
|
+
var utils_messages = require('./messages.cjs');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Runs `rule` against `tree` and swallows any error it throws, logging `fallbackMessage` instead. Meant for
|
|
9
|
+
* `addRootProvider`, which throws on a bootstrap it cannot analyze statically, such as a custom bootstrap or a missing
|
|
10
|
+
* `build` target. What the rule changed before it threw stays: `addRootProvider` adds its imports first.
|
|
11
|
+
*/
|
|
12
|
+
function safeRule(rule, fallbackMessage) {
|
|
13
|
+
return async (tree, context) => {
|
|
14
|
+
try {
|
|
15
|
+
await rxjs.firstValueFrom(schematics.callRule(rule, tree, context));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
utils_messages.logMessage(context.logger, fallbackMessage);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.safeRule = safeRule;
|