@koobiq/components 20.1.0 → 20.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/accordion/_accordion-theme.scss +6 -2
  2. package/accordion/accordion-tokens.scss +3 -0
  3. package/accordion/{accordion-trigger.component.scss → accordion-trigger.scss} +10 -0
  4. package/accordion/accordion.scss +71 -0
  5. package/accordion/index.d.ts +264 -121
  6. package/actions-panel/index.d.ts +25 -13
  7. package/alert/_alert-theme.scss +14 -0
  8. package/alert/alert.component.scss +24 -13
  9. package/alert/index.d.ts +63 -29
  10. package/app-switcher/app-switcher-dropdown-app.scss +7 -5
  11. package/app-switcher/app-switcher-dropdown-site.scss +6 -4
  12. package/app-switcher/index.d.ts +41 -4
  13. package/app-switcher/kbq-app-switcher-list-item.scss +6 -8
  14. package/autocomplete/autocomplete.scss +2 -1
  15. package/autocomplete/index.d.ts +58 -37
  16. package/badge/index.d.ts +2 -3
  17. package/breadcrumbs/index.d.ts +1 -1
  18. package/button/index.d.ts +2 -2
  19. package/button-toggle/button-toggle-tokens.scss +2 -0
  20. package/button-toggle/button-toggle.scss +9 -0
  21. package/button-toggle/index.d.ts +5 -0
  22. package/checkbox/index.d.ts +33 -29
  23. package/clamped-text/index.d.ts +3 -2
  24. package/code-block/index.d.ts +24 -19
  25. package/content-panel/index.d.ts +1 -1
  26. package/core/index.d.ts +1217 -186
  27. package/core/option/_action-container-mixins.scss +28 -0
  28. package/core/option/_option-theme.scss +24 -0
  29. package/core/option/action.scss +7 -0
  30. package/core/styles/_core.scss +2 -0
  31. package/core/styles/_koobiq-theme.scss +2 -0
  32. package/core/styles/_tokens.scss +1 -0
  33. package/core/styles/common/_animation.scss +31 -24
  34. package/core/styles/common/_connected-overlay.scss +39 -0
  35. package/core/styles/common/_select.scss +19 -2
  36. package/core/styles/common/_tokens.scss +0 -9
  37. package/core/styles/theming/_index.scss +0 -1
  38. package/core/styles/theming/_theming.scss +34 -5
  39. package/datepicker/index.d.ts +46 -15
  40. package/dl/dl.scss +26 -0
  41. package/dl/index.d.ts +8 -1
  42. package/dropdown/_dropdown-theme.scss +28 -2
  43. package/dropdown/dropdown-item.scss +29 -0
  44. package/dropdown/dropdown-tokens.scss +2 -1
  45. package/dropdown/dropdown.scss +16 -1
  46. package/dropdown/index.d.ts +331 -17
  47. package/dynamic-translation/index.d.ts +1 -1
  48. package/fesm2022/koobiq-components-accordion.mjs +480 -317
  49. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  50. package/fesm2022/koobiq-components-actions-panel.mjs +57 -46
  51. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  52. package/fesm2022/koobiq-components-alert.mjs +98 -58
  53. package/fesm2022/koobiq-components-alert.mjs.map +1 -1
  54. package/fesm2022/koobiq-components-app-switcher.mjs +233 -38
  55. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  56. package/fesm2022/koobiq-components-autocomplete.mjs +89 -52
  57. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  58. package/fesm2022/koobiq-components-badge.mjs +18 -17
  59. package/fesm2022/koobiq-components-badge.mjs.map +1 -1
  60. package/fesm2022/koobiq-components-breadcrumbs.mjs +25 -25
  61. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  62. package/fesm2022/koobiq-components-button-toggle.mjs +17 -12
  63. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  64. package/fesm2022/koobiq-components-button.mjs +25 -25
  65. package/fesm2022/koobiq-components-checkbox.mjs +69 -92
  66. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  67. package/fesm2022/koobiq-components-clamped-text.mjs +18 -13
  68. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  69. package/fesm2022/koobiq-components-code-block.mjs +56 -69
  70. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  71. package/fesm2022/koobiq-components-content-panel.mjs +29 -29
  72. package/fesm2022/koobiq-components-core.mjs +2485 -735
  73. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  74. package/fesm2022/koobiq-components-datepicker.mjs +168 -126
  75. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  76. package/fesm2022/koobiq-components-divider.mjs +7 -7
  77. package/fesm2022/koobiq-components-dl.mjs +23 -15
  78. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  79. package/fesm2022/koobiq-components-dropdown.mjs +814 -136
  80. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  81. package/fesm2022/koobiq-components-dynamic-translation.mjs +13 -13
  82. package/fesm2022/koobiq-components-ellipsis-center.mjs +7 -7
  83. package/fesm2022/koobiq-components-empty-state.mjs +19 -19
  84. package/fesm2022/koobiq-components-file-upload.mjs +74 -42
  85. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-filter-bar.mjs +783 -199
  87. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  88. package/fesm2022/koobiq-components-flag.mjs +7 -7
  89. package/fesm2022/koobiq-components-form-field.mjs +350 -162
  90. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  91. package/fesm2022/koobiq-components-icon.mjs +52 -25
  92. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  93. package/fesm2022/koobiq-components-inline-edit.mjs +175 -28
  94. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  95. package/fesm2022/koobiq-components-input.mjs +41 -24
  96. package/fesm2022/koobiq-components-input.mjs.map +1 -1
  97. package/fesm2022/koobiq-components-link.mjs +8 -8
  98. package/fesm2022/koobiq-components-list.mjs +657 -143
  99. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-loader-overlay.mjs +16 -16
  101. package/fesm2022/koobiq-components-markdown.mjs +14 -11
  102. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  103. package/fesm2022/koobiq-components-modal.mjs +59 -35
  104. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  105. package/fesm2022/koobiq-components-navbar.mjs +177 -67
  106. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  107. package/fesm2022/koobiq-components-notification-center.mjs +40 -24
  108. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  109. package/fesm2022/koobiq-components-overflow-items.mjs +16 -17
  110. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  111. package/fesm2022/koobiq-components-popover.mjs +31 -21
  112. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  113. package/fesm2022/koobiq-components-progress-bar.mjs +13 -13
  114. package/fesm2022/koobiq-components-progress-spinner.mjs +13 -13
  115. package/fesm2022/koobiq-components-radio.mjs +10 -10
  116. package/fesm2022/koobiq-components-resizer.mjs +33 -14
  117. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  118. package/fesm2022/koobiq-components-scrollbar.mjs +10 -10
  119. package/fesm2022/koobiq-components-search-expandable.mjs +49 -14
  120. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  121. package/fesm2022/koobiq-components-select.mjs +450 -146
  122. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  123. package/fesm2022/koobiq-components-sidebar.mjs +14 -14
  124. package/fesm2022/koobiq-components-sidepanel.mjs +26 -26
  125. package/fesm2022/koobiq-components-skeleton.mjs +10 -10
  126. package/fesm2022/koobiq-components-split-button.mjs +10 -17
  127. package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
  128. package/fesm2022/koobiq-components-splitter.mjs +17 -17
  129. package/fesm2022/koobiq-components-table.mjs +15 -13
  130. package/fesm2022/koobiq-components-table.mjs.map +1 -1
  131. package/fesm2022/koobiq-components-tabs.mjs +80 -68
  132. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  133. package/fesm2022/koobiq-components-tags.mjs +283 -122
  134. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  135. package/fesm2022/koobiq-components-textarea.mjs +13 -8
  136. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  137. package/fesm2022/koobiq-components-time-range.mjs +29 -24
  138. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  139. package/fesm2022/koobiq-components-timepicker.mjs +61 -30
  140. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  141. package/fesm2022/koobiq-components-timezone.mjs +77 -42
  142. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  143. package/fesm2022/koobiq-components-title.mjs +7 -7
  144. package/fesm2022/koobiq-components-toast.mjs +51 -26
  145. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  146. package/fesm2022/koobiq-components-toggle.mjs +72 -64
  147. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  148. package/fesm2022/koobiq-components-tooltip.mjs +219 -28
  149. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  150. package/fesm2022/koobiq-components-top-bar.mjs +13 -13
  151. package/fesm2022/koobiq-components-tree-select.mjs +222 -80
  152. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  153. package/fesm2022/koobiq-components-tree.mjs +302 -81
  154. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  155. package/fesm2022/koobiq-components-username.mjs +27 -27
  156. package/file-upload/index.d.ts +25 -6
  157. package/file-upload/multiple-file-upload.component.scss +14 -0
  158. package/filter-bar/_filter-bar-theme.scss +0 -10
  159. package/filter-bar/filter-bar-tokens.scss +3 -0
  160. package/filter-bar/filters.scss +3 -2
  161. package/filter-bar/index.d.ts +281 -9
  162. package/filter-bar/pipes/base-pipe.scss +0 -11
  163. package/filter-bar/pipes/pipe-input.scss +10 -0
  164. package/filter-bar/pipes/pipe-multi-tree-select.scss +0 -6
  165. package/filter-bar/pipes/pipe-multiselect.scss +0 -6
  166. package/filter-bar/pipes/pipe-tree-select.scss +0 -6
  167. package/form-field/_form-field-theme.scss +76 -20
  168. package/form-field/fieldset.scss +10 -0
  169. package/form-field/form-field-tokens.scss +15 -1
  170. package/form-field/form-field.scss +15 -19
  171. package/form-field/index.d.ts +147 -65
  172. package/icon/icon-button.scss +3 -1
  173. package/icon/index.d.ts +45 -7
  174. package/inline-edit/index.d.ts +57 -4
  175. package/inline-edit/inline-edit.scss +10 -0
  176. package/input/index.d.ts +17 -2
  177. package/list/_list-theme.scss +42 -10
  178. package/list/index.d.ts +326 -79
  179. package/list/list-tokens.scss +43 -8
  180. package/list/list.scss +186 -12
  181. package/markdown/index.d.ts +1 -1
  182. package/modal/index.d.ts +21 -4
  183. package/modal/modal-tokens.scss +1 -1
  184. package/navbar/_navbar-item_vertical.scss +7 -5
  185. package/navbar/index.d.ts +54 -5
  186. package/navbar/navbar-brand.scss +23 -7
  187. package/navbar/vertical-navbar.scss +6 -0
  188. package/notification-center/index.d.ts +2 -1
  189. package/notification-center/notification-item.scss +6 -0
  190. package/package.json +3 -6
  191. package/popover/index.d.ts +2 -2
  192. package/prebuilt-themes/dark-theme.css +1 -1
  193. package/prebuilt-themes/light-theme.css +1 -1
  194. package/prebuilt-themes/theme.css +1 -1
  195. package/resizer/index.d.ts +12 -0
  196. package/schematics/collection.json +10 -0
  197. package/schematics/migrations/alert-signals/README.md +64 -0
  198. package/schematics/migrations/alert-signals/data.js +70 -0
  199. package/schematics/migrations/alert-signals/index.js +350 -0
  200. package/schematics/migrations/alert-signals/schema.json +20 -0
  201. package/schematics/migrations/autocomplete-panel-width-auto/README.md +68 -0
  202. package/schematics/migrations/autocomplete-panel-width-auto/index.js +70 -0
  203. package/schematics/migrations/autocomplete-panel-width-auto/schema.json +15 -0
  204. package/schematics/migrations/deprecated-icons/README.md +29 -4
  205. package/schematics/migrations/deprecated-icons/data.js +7 -0
  206. package/schematics/migrations/deprecated-icons/index.js +62 -35
  207. package/schematics/migrations/filter-bar-signals/README.md +1 -1
  208. package/schematics/migrations/new-icons-pack/README.md +37 -2
  209. package/schematics/migrations/new-icons-pack/data.js +8 -0
  210. package/schematics/migrations/new-icons-pack/index.js +144 -53
  211. package/schematics/migrations.json +11 -1
  212. package/schematics/ng-add/index.js +3 -3
  213. package/schematics/utils/angular-parsing.js +41 -14
  214. package/schematics/utils/ast.js +31 -0
  215. package/schematics/utils/icon-migration.js +530 -0
  216. package/schematics/utils/typescript.js +44 -0
  217. package/scrollbar/index.d.ts +1 -1
  218. package/search-expandable/index.d.ts +3 -0
  219. package/select/index.d.ts +212 -40
  220. package/select/select-tokens.scss +0 -1
  221. package/select/select.scss +0 -2
  222. package/splitter/index.d.ts +1 -1
  223. package/table/_table-theme.scss +4 -0
  224. package/table/index.d.ts +2 -1
  225. package/table/table.scss +8 -0
  226. package/tabs/_tabs-common.scss +60 -31
  227. package/tabs/_tabs-theme.scss +12 -0
  228. package/tabs/index.d.ts +2 -2
  229. package/tabs/tab-header.scss +14 -0
  230. package/tabs/tab-nav-bar.scss +4 -0
  231. package/tabs/tabs-tokens.scss +1 -0
  232. package/tags/index.d.ts +128 -29
  233. package/textarea/index.d.ts +5 -0
  234. package/time-range/index.d.ts +1 -1
  235. package/timepicker/index.d.ts +4 -0
  236. package/timezone/index.d.ts +10 -8
  237. package/toast/index.d.ts +26 -3
  238. package/toggle/index.d.ts +34 -14
  239. package/tooltip/index.d.ts +119 -7
  240. package/tree/_tree-theme.scss +25 -5
  241. package/tree/index.d.ts +71 -3
  242. package/tree/tree-option.scss +2 -8
  243. package/tree-select/_tree-select-theme.scss +22 -0
  244. package/tree-select/index.d.ts +127 -36
  245. package/accordion/accordion.component.scss +0 -50
  246. package/core/styles/_tokens.kbq.import.scss +0 -4
  247. package/core/styles/theming/_components-theming.scss +0 -1927
  248. package/filter-bar/pipes/pipe-select.scss +0 -5
  249. package/overflow-items/overflow-items.scss +0 -20
@@ -1,11 +1,36 @@
1
- ### New Icons Pack schematics
1
+ ### Deprecated Icons schematics
2
2
 
3
- This schematic provides migration for update icons pack. It includes:
3
+ This schematic provides migration away from the deprecated `pt-icons` scope. It includes:
4
4
 
5
- - Change prefixes from `mc` to `kbq` for ts, html, styles
6
- - Update icon names for updated/removed icons according to [mapping](data.ts)
5
+ - Change the `pt-icons` scope/prefix to `kbq` in `class` attributes, `kbq-icon`/`kbq-icon-item`/`kbq-icon-button`
6
+ attribute values, `[class.pt-icons-*]` bindings, and bare string literals — for TS, HTML, and styles
7
+ - Update icon names for deprecated icons according to [mapping](data.ts)
7
8
  - Fix icons package prefix in styles
8
9
 
10
+ Matching is AST-based (parsed HTML/TypeScript, not whole-file text search), so it only touches genuine icon
11
+ usages — e.g. a component selector, a `[class]` binding expression, or an unrelated class/variable that merely
12
+ contains the substring `pt-icons` is left alone. It also covers a component's inline `host` class bindings and
13
+ inline `styles` array, and icons inside ICU expansions (`{count, plural, ...}`). A bound attribute value that
14
+ isn't a single quoted literal (a dynamic expression, a concatenation, or `{{ }}` interpolation) can't be
15
+ resolved statically — it's reported as a warning rather than migrated or silently corrupted. An icon whose
16
+ scope prefix was already swapped to `kbq-` by an earlier run (e.g. `kbq-icon="kbq-add-to-list_16"`) still gets
17
+ its name corrected.
18
+
19
+ One documented exception: in style files there's no CSS/SCSS parser, so token matching is a
20
+ word/selector-boundary-safe regex rather than real selector parsing — this correctly ignores
21
+ `.my-widget-pt-icons-preview`, `$pt-icons`, and `@import 'pt-icons'` (the bare scope word only matches when
22
+ directly preceded by `.`, like a real class selector), but a genuine selector spelled out inside a comment is
23
+ still indistinguishable from one that isn't and can still be rewritten.
24
+
25
+ Two intentional behavior changes from earlier versions of this schematic:
26
+
27
+ - `class="pt-icons"` (the sole class) now becomes `class=""` rather than removing the `class` attribute
28
+ entirely.
29
+ - A bare string literal like `'pt-icons word-wrap_16'` now also renames the icon suffix (e.g. to
30
+ `'wrap-text_16'`), instead of only stripping the scope word.
31
+
32
+ `fix: false` (the default) never mutates any file — it only reports what it found.
33
+
9
34
  [Params](schema.ts)
10
35
 
11
36
  Usage for Angular Cli:
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ /**
4
+ * @deprecated Unused by this migration. Kept only so external code importing this array doesn't
5
+ * break. Use `scope` below instead.
6
+ */
3
7
  const iconClassReplacements = [
4
8
  { replace: 'kbq-icon="pt-icons-', replaceWith: 'kbq-icon="kbq-' },
5
9
  { replace: 'pt-icons-', replaceWith: 'kbq-' },
@@ -9,6 +13,8 @@ const iconClassReplacements = [
9
13
  { replace: "'pt-icons ", replaceWith: "'" },
10
14
  { replace: '\\.pt-icons', replaceWith: '.kbq' }
11
15
  ];
16
+ /** Old scope prefix and its replacement, used to build the migration's icon token map. */
17
+ const scope = { from: 'pt-icons', to: 'kbq' };
12
18
  const iconsMapping = [
13
19
  {
14
20
  replace: 'add-to-list_16',
@@ -1578,3 +1584,4 @@ const iconsMapping = [
1578
1584
 
1579
1585
  exports.iconClassReplacements = iconClassReplacements;
1580
1586
  exports.iconsMapping = iconsMapping;
1587
+ exports.scope = scope;
@@ -3,9 +3,14 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var path = require('path');
6
+ var utils_angularParsing = require('../../utils/angular-parsing.js');
7
+ var utils_iconMigration = require('../../utils/icon-migration.js');
6
8
  var utils_messages = require('../../utils/messages.js');
7
9
  var utils_packageConfig = require('../../utils/package-config.js');
8
10
  var migrations_deprecatedIcons_data = require('./data.js');
11
+ require('typescript');
12
+ require('../../utils/ast.js');
13
+ require('../../utils/typescript.js');
9
14
  require('@angular-devkit/schematics');
10
15
  require('@schematics/angular/utility');
11
16
 
@@ -29,6 +34,13 @@ function _interopNamespaceDefault(e) {
29
34
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
30
35
 
31
36
  const iconsFontImportRule = "@use '@koobiq/icons/fonts/kbq-icons';";
37
+ const migrationData = {
38
+ valueAttrs: ['kbq-icon', 'kbq-icon-item', 'kbq-icon-button'],
39
+ scope: migrations_deprecatedIcons_data.scope,
40
+ scopeClassInList: 'remove',
41
+ icons: migrations_deprecatedIcons_data.iconsMapping.map(({ replace, replaceWith }) => ({ from: replace, to: replaceWith })),
42
+ rescopeUnknownValues: true
43
+ };
32
44
  function deprecatedIcons(options) {
33
45
  let targetDir;
34
46
  return async (tree, context) => {
@@ -41,46 +53,61 @@ function deprecatedIcons(options) {
41
53
  targetDir = tree;
42
54
  }
43
55
  const { logger } = context;
44
- const handleDeprecatedIcons = (newContent, filePath) => {
45
- if (fix) {
46
- migrations_deprecatedIcons_data.iconsMapping.forEach(({ replace, replaceWith }) => {
47
- newContent = newContent.replace(new RegExp(`kbq-${replace}`, 'g'), `kbq-${replaceWith}`);
48
- });
49
- }
50
- else {
51
- const foundIcons = migrations_deprecatedIcons_data.iconsMapping.filter(({ replace }) => newContent.indexOf(replace) !== -1);
52
- if (foundIcons.length) {
53
- const parsedFilePath = path__namespace.relative(__dirname, `.${filePath}`).replace(/\\/g, '/');
54
- utils_messages.logMessage(logger, [
55
- `Please pay attention! Found deprecated icons in file: `,
56
- parsedFilePath,
57
- foundIcons.map(({ replace, replaceWith }) => `\t${replace} -> \t${replaceWith}`).join('\n')
58
- ]);
59
- }
60
- }
61
- return newContent;
56
+ const tokenMap = utils_iconMigration.buildIconTokenMap(migrationData);
57
+ // Unlike a `class` list (where the bare scope token is simply dropped, e.g.
58
+ // `class="pt-icons"` -> `class=""`), a stylesheet selector renames the scope class itself
59
+ // (e.g. `.pt-icons` -> `.kbq`) rather than removing it.
60
+ const styleTokenMap = new Map(tokenMap).set(migrationData.scope.from, migrationData.scope.to);
61
+ // Precompiled once and reused across every .ts/style file below, instead of rebuilding
62
+ // every regex per file.
63
+ const stylePatterns = utils_iconMigration.buildIconTokenPatterns(styleTokenMap, migrationData.scope.from);
64
+ const onFound = (filePath, found) => {
65
+ const parsedFilePath = path__namespace.relative(__dirname, `.${filePath}`).replace(/\\/g, '/');
66
+ utils_messages.logMessage(logger, [
67
+ `Please pay attention! Found deprecated icons in file: `,
68
+ parsedFilePath,
69
+ found.map(({ from, to }) => `\t${from} -> \t${to}`).join('\n')
70
+ ]);
62
71
  };
63
- // Update styles, templates & components
64
- targetDir.visit((filePath, entry) => {
65
- let initialContent;
66
- // if project property not provided, skip files in node_modules & dist
67
- if (filePath.includes('node_modules') || filePath.includes('dist')) {
72
+ const warn = (message) => logger.warn(message);
73
+ const templatePaths = [];
74
+ const tsPaths = [];
75
+ const stylePaths = [];
76
+ // if project property not provided, skip files in node_modules & dist
77
+ targetDir.visit((filePath) => {
78
+ if (filePath.includes('node_modules') || filePath.includes('/dist/')) {
68
79
  return;
69
80
  }
70
- if (filePath.endsWith('.html') || filePath.endsWith('.ts') || filePath.endsWith(stylesExt)) {
71
- initialContent = entry?.content.toString();
72
- let newContent = initialContent;
73
- if (newContent) {
74
- migrations_deprecatedIcons_data.iconClassReplacements.forEach(({ replace, replaceWith }) => {
75
- newContent = newContent.replace(new RegExp(replace, 'g'), replaceWith);
76
- });
77
- newContent = handleDeprecatedIcons(newContent, filePath);
78
- if (initialContent !== newContent) {
79
- tree.overwrite(filePath, newContent || '');
80
- }
81
- }
81
+ if (filePath.endsWith('.html')) {
82
+ templatePaths.push(filePath);
83
+ }
84
+ else if (filePath.endsWith('.ts') &&
85
+ !filePath.endsWith('.d.ts') &&
86
+ !filePath.endsWith('.ngtypecheck.ts')) {
87
+ tsPaths.push(filePath);
88
+ }
89
+ else if (filePath.endsWith(stylesExt)) {
90
+ stylePaths.push(filePath);
82
91
  }
83
92
  });
93
+ // Update external html
94
+ await utils_angularParsing.migrateTemplateWithTransform(tree, templatePaths, context, utils_iconMigration.createIconTemplateTransform(migrationData, tokenMap, { fix, onFound, warn }));
95
+ // Update inline html & bare string literals in components
96
+ await utils_iconMigration.migrateIconsInTsFiles(tree, tsPaths, context, migrationData, tokenMap, { fix, onFound, warn }, stylePatterns);
97
+ // Update styles
98
+ for (const filePath of stylePaths) {
99
+ const initialContent = tree.read(filePath)?.toString();
100
+ if (!initialContent) {
101
+ continue;
102
+ }
103
+ const { content, changed, found } = utils_iconMigration.replaceKnownIconTokens(initialContent, stylePatterns, fix);
104
+ if (found.length && !fix) {
105
+ onFound(filePath, found);
106
+ }
107
+ if (changed) {
108
+ tree.overwrite(filePath, content);
109
+ }
110
+ }
84
111
  // check if icon styles from new scope should be included in styles file
85
112
  targetDir.visit((filePath, entry) => {
86
113
  if (filePath.endsWith(stylesExt) && !entry?.content.toString()?.includes(iconsFontImportRule)) {
@@ -1,6 +1,6 @@
1
1
  # filter-bar-signals
2
2
 
3
- Migration schematic invoked automatically by `ng update @koobiq/components@21`.
3
+ Migration schematic invoked automatically by `ng update @koobiq/components@20`.
4
4
  Migrates consumers of `KbqFilterBar` to its signal-based public API.
5
5
 
6
6
  ## Why
@@ -7,6 +7,37 @@ This schematic provides migration for update icons pack. It includes:
7
7
  - Fix icons package prefix in styles
8
8
  - Optionally use custom migration and replacement data
9
9
 
10
+ Matching is AST-based (parsed HTML/TypeScript, not whole-file text search), so it only touches genuine icon
11
+ usages — a component selector like `<mc-button>`, a `[class]` binding expression, an unrelated class such as
12
+ `.mc-panel-header`, or an unrelated string like `'mc-legacy-mode'` are all left untouched. It also covers a
13
+ component's inline `host` class bindings and inline `styles` array, and icons inside ICU expansions
14
+ (`{count, plural, ...}`). A bound attribute value that isn't a single quoted literal (a dynamic expression, a
15
+ concatenation, or `{{ }}` interpolation) can't be resolved statically — it's reported as a warning rather than
16
+ migrated or silently corrupted. An icon whose prefix was already swapped to `kbq-` by an earlier run (e.g.
17
+ `kbq-icon="kbq-add-to-list_16"`) still gets its name corrected.
18
+
19
+ One documented exception: in style files (and `.md` docs) there's no CSS/SCSS parser, so token matching is a
20
+ word/selector-boundary-safe regex rather than real selector parsing — this correctly ignores `.my-mc-widget`,
21
+ `$mc`, and `@import 'mc'` (the bare scope word only matches when directly preceded by `.`, like a real class
22
+ selector), but a genuine selector spelled out inside a comment is still indistinguishable from one that isn't
23
+ and can still be rewritten.
24
+
25
+ `fix: false` (the default) never mutates any file — it only reports what it found. Icon-_name_ renames (e.g.
26
+ `mc-add-to-list_16`/`kbq-add-to-list_16` → the current `kbq-file-plus-o_16`) always apply in styles/`.md`
27
+ regardless of `updatePrefix`; the option only gates the _bare_ scope-word rename (`mc` → `kbq`) there. In
28
+ templates/TS, icon-attribute values are always matched regardless of `updatePrefix`.
29
+
30
+ #### `--custom-icon-replacement-path`
31
+
32
+ The expected file shape changed. It's still a JSON array of `{ "replace": ..., "replaceWith": ... }` objects,
33
+ but each entry is now interpreted as a bare scope-word pair (e.g. `{ "replace": "mc", "replaceWith": "kbq" }`,
34
+ with no leading/trailing hyphen) rather than a whole-file regex fragment like `kbq-icon="mc-` — the AST-based
35
+ matcher no longer needs per-context fragments. A file still written in the old fragment style, or a malformed
36
+ one, is detected and ignored with a warning (falling back to the default `mc` → `kbq` scope) rather than being
37
+ silently misapplied or crashing. [`replacement.json`](replacement.json) is kept in its old fragment shape for
38
+ backward compatibility with anyone already pointing at it — **don't** pass it via `--custom-icon-replacement-path`
39
+ as-is (see the fallback warning above); copy it into your own file and rewrite it in the new shape instead.
40
+
10
41
  ---
11
42
 
12
43
  ### Parameters
@@ -47,11 +78,15 @@ ng g @koobiq/components:new-icons-pack --fix=true --project <your project>
47
78
  ```shell
48
79
  ng g @koobiq/components:new-icons-pack \
49
80
  --custom-data-path migration.json \
50
- --custom-icon-replacement-path replacement.json \
81
+ --custom-icon-replacement-path my-replacement.json \
51
82
  --fix=true \
52
83
  --project <your-project>
53
84
  ```
54
85
 
86
+ `migration.json` is the shipped icon-name mapping and can be used as-is. `my-replacement.json` is a file you
87
+ write yourself, in the new bare scope-word-pair shape described above — **not** the shipped
88
+ [`replacement.json`](replacement.json), which is still in the legacy shape.
89
+
55
90
  #### Nx
56
91
 
57
92
  ```shell
@@ -63,7 +98,7 @@ nx g @koobiq/components:new-icons-pack --fix=true --project <your project>
63
98
  ```shell
64
99
  nx g @koobiq/components:new-icons-pack \
65
100
  --custom-data-path migration.json \
66
- --custom-icon-replacement-path replacement.json \
101
+ --custom-icon-replacement-path my-replacement.json \
67
102
  --fix=true \
68
103
  --project <your-project>
69
104
  ```
@@ -1,5 +1,10 @@
1
1
  'use strict';
2
2
 
3
+ /**
4
+ * @deprecated Unused by this migration. Kept only so external code importing this array doesn't
5
+ * break, and so a `customIconReplacementPath` file still written in this shape can be detected and
6
+ * warned about (see `resolveScope` in `./index.ts`). Use `scope` below instead.
7
+ */
3
8
  const iconReplacements = [
4
9
  { replace: 'kbq-icon="mc-', replaceWith: 'kbq-icon="kbq-' },
5
10
  { replace: 'kbq-icon-item="mc-', replaceWith: 'kbq-icon-item="kbq-' },
@@ -12,6 +17,8 @@ const iconReplacements = [
12
17
  { replace: "'mc-", replaceWith: "'kbq-" },
13
18
  { replace: `\\.mc;`, replaceWith: `.kbq;` }
14
19
  ];
20
+ /** Old scope prefix and its replacement, used to build the migration's icon token map. */
21
+ const scope = { from: 'mc', to: 'kbq' };
15
22
  const newIconsPackData = [
16
23
  {
17
24
  replaceWith: 'kbq-3-columns_32',
@@ -2301,3 +2308,4 @@ const newIconsPackData = [
2301
2308
 
2302
2309
  exports.iconReplacements = iconReplacements;
2303
2310
  exports.newIconsPackData = newIconsPackData;
2311
+ exports.scope = scope;
@@ -4,9 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var fs = require('fs');
6
6
  var path = require('path');
7
+ var utils_angularParsing = require('../../utils/angular-parsing.js');
8
+ var utils_iconMigration = require('../../utils/icon-migration.js');
7
9
  var utils_messages = require('../../utils/messages.js');
8
10
  var utils_packageConfig = require('../../utils/package-config.js');
9
11
  var migrations_newIconsPack_data = require('./data.js');
12
+ require('typescript');
13
+ require('../../utils/ast.js');
14
+ require('../../utils/typescript.js');
10
15
  require('@angular-devkit/schematics');
11
16
  require('@schematics/angular/utility');
12
17
 
@@ -34,14 +39,59 @@ function readJsonFile(filePath) {
34
39
  const fileContents = fs.readFileSync(absolutePath, 'utf-8');
35
40
  return JSON.parse(fileContents);
36
41
  }
42
+ // A bare word: no leading/trailing hyphen, no empty hyphen-separated segment (rejects e.g. `mc-`,
43
+ // which is otherwise the most natural — and wrong, per the new engine's key-building — way to
44
+ // write a "prefix" pair).
45
+ const BARE_SCOPE_WORD = /^\w+(-\w+)*$/;
46
+ /** `newIconsPackData`/`migration.json` always author their `replace`/`replaceWith` pair under
47
+ * this literal scope — independent of whatever scope the user is migrating *to* via
48
+ * `customIconReplacementPath` — so it's always the first prefix stripped. */
49
+ const CANONICAL_ICON_DATA_SCOPE = 'kbq';
50
+ /** Strips a known scope prefix (e.g. `mc-`/`kbq-`) from a token, if present. */
51
+ function stripScopePrefix(value, prefixes) {
52
+ for (const prefix of prefixes) {
53
+ if (value.startsWith(`${prefix}-`)) {
54
+ return value.slice(prefix.length + 1);
55
+ }
56
+ }
57
+ return value;
58
+ }
59
+ function isBareScopePair(entry) {
60
+ return (typeof entry?.replace === 'string' &&
61
+ typeof entry?.replaceWith === 'string' &&
62
+ BARE_SCOPE_WORD.test(entry.replace) &&
63
+ BARE_SCOPE_WORD.test(entry.replaceWith));
64
+ }
65
+ /**
66
+ * Resolves the scope pair from a `customIconReplacementPath` file: a bare scope-word pair (e.g.
67
+ * `{ "replace": "mc", "replaceWith": "kbq" }`). A legacy-shaped or malformed entry is detected and
68
+ * warned about instead of silently misapplied — or crashed on.
69
+ */
70
+ function resolveScope(entries, fallback, logger) {
71
+ if (!Array.isArray(entries)) {
72
+ logger.warn('customIconReplacementPath must contain a JSON array of { "replace", "replaceWith" } entries. ' +
73
+ 'Falling back to the default scope.');
74
+ return fallback;
75
+ }
76
+ const valid = entries.find(isBareScopePair);
77
+ if (!valid) {
78
+ if (entries.length) {
79
+ logger.warn('customIconReplacementPath entries look like the legacy fragment format and were ignored. ' +
80
+ 'See new-icons-pack/README.md for the new expected shape (e.g. { "replace": "mc", "replaceWith": "kbq" }).');
81
+ }
82
+ return fallback;
83
+ }
84
+ return { from: valid.replace, to: valid.replaceWith };
85
+ }
37
86
  function newIconsPack(options) {
38
87
  let targetDir;
39
88
  return async (tree, context) => {
40
89
  const { project, fix, stylesExt, updatePrefix = true, customDataPath, customIconReplacementPath } = options;
90
+ const { logger } = context;
41
91
  const resolvedData = customDataPath ? readJsonFile(customDataPath) : migrations_newIconsPack_data.newIconsPackData;
42
- const resolvedIconsReplacements = customIconReplacementPath
43
- ? readJsonFile(customIconReplacementPath)
44
- : migrations_newIconsPack_data.iconReplacements;
92
+ const resolvedScope = customIconReplacementPath
93
+ ? resolveScope(readJsonFile(customIconReplacementPath), migrations_newIconsPack_data.scope, logger)
94
+ : migrations_newIconsPack_data.scope;
45
95
  try {
46
96
  const projectDefinition = await utils_packageConfig.setupOptions(project, tree);
47
97
  targetDir = projectDefinition ? tree.getDir(projectDefinition.root) : tree;
@@ -49,65 +99,106 @@ function newIconsPack(options) {
49
99
  catch {
50
100
  targetDir = tree;
51
101
  }
52
- const { logger } = context;
53
- const handleDeprecatedIcons = (newContent, filePath) => {
54
- if (fix) {
55
- resolvedData.forEach(({ replace, replaceWith }) => {
56
- newContent = newContent.replace(new RegExp(replace, 'g'), replaceWith);
57
- });
58
- }
59
- else {
60
- const foundIcons = resolvedData.filter(({ replace }) => newContent.indexOf(replace) !== -1);
61
- if (foundIcons.length) {
62
- const parsedFilePath = path__namespace.relative(__dirname, `.${filePath}`).replace(/\\/g, '/');
63
- utils_messages.logMessage(logger, [
64
- `Please pay attention! Found deprecated icons in file: `,
65
- parsedFilePath,
66
- foundIcons.map(({ replace, replaceWith }) => `\t${replace} -> \t${replaceWith}`).join('\n')
67
- ]);
68
- }
69
- }
70
- return newContent;
102
+ const migrationData = {
103
+ valueAttrs: ['kbq-icon', 'kbq-icon-item', 'kbq-icon-button'],
104
+ scope: resolvedScope,
105
+ scopeClassInList: 'rename',
106
+ // `replace`/`replaceWith` are always authored under `CANONICAL_ICON_DATA_SCOPE`
107
+ // ('kbq-'), regardless of the scope this run is migrating *to* — falls back to
108
+ // stripping the target scope for a custom data file that doesn't follow that
109
+ // convention.
110
+ icons: resolvedData.map(({ replace, replaceWith }) => ({
111
+ from: stripScopePrefix(replace, [CANONICAL_ICON_DATA_SCOPE, resolvedScope.to, resolvedScope.from]),
112
+ to: stripScopePrefix(replaceWith, [CANONICAL_ICON_DATA_SCOPE, resolvedScope.to])
113
+ })),
114
+ // Only the attribute-value path (`kbq-icon="mc-<anything>"`) rescopes suffixes that
115
+ // aren't a known icon name; class lists/bindings/strings/styles stay exact-token-only.
116
+ // This runs unconditionally in templates/TS `updatePrefix` only gates the bare
117
+ // scope-word rename in the (separate, unscoped-by-nature) styles/markdown pass below.
118
+ rescopeUnknownValues: true
71
119
  };
120
+ const tokenMap = utils_iconMigration.buildIconTokenMap(migrationData);
121
+ // Icon-name renames (e.g. `mc-add-to-list_16` / `kbq-add-to-list_16` -> the current
122
+ // `kbq-file-plus-o_16`) apply to styles/markdown regardless of `updatePrefix` — only the
123
+ // *bare* scope-word rename (`mc` -> `kbq`, which touches `$mc`/`@import 'mc'` as much as a
124
+ // real `.mc {}` selector) is gated by it, matching the option's historical scope.
125
+ const styleAndMarkdownTokenMap = updatePrefix
126
+ ? tokenMap
127
+ : new Map([...tokenMap].filter(([token]) => token !== resolvedScope.from));
128
+ // Precompiled once and reused across every relevant file below, instead of rebuilding
129
+ // ~1000+ regexes per file. Inline `styles` arrays inside `.ts` files use the unfiltered
130
+ // `tokenMap` (matching `migrateIconsInTsFiles`'s pre-existing behavior); real `.scss`/`.md`
131
+ // files use `styleAndMarkdownTokenMap`, which additionally respects `updatePrefix`.
132
+ const tsInlineStylePatterns = utils_iconMigration.buildIconTokenPatterns(tokenMap, resolvedScope.from);
133
+ const stylePatterns = utils_iconMigration.buildIconTokenPatterns(styleAndMarkdownTokenMap, resolvedScope.from);
134
+ const onFound = (filePath, found) => {
135
+ const parsedFilePath = path__namespace.relative(__dirname, `.${filePath}`).replace(/\\/g, '/');
136
+ utils_messages.logMessage(logger, [
137
+ `Please pay attention! Found deprecated icons in file: `,
138
+ parsedFilePath,
139
+ found.map(({ from, to }) => `\t${from} -> \t${to}`).join('\n')
140
+ ]);
141
+ };
142
+ const warn = (message) => logger.warn(message);
143
+ const templatePaths = [];
144
+ const tsPaths = [];
145
+ const markdownPaths = [];
72
146
  // Update templates & components
73
- targetDir.visit((path, entry) => {
147
+ targetDir.visit((filePath) => {
74
148
  // if project property not provided, skip files in node_modules & dist
75
- if (path.includes('node_modules') || path.includes('dist')) {
149
+ if (filePath.includes('node_modules') || filePath.includes('/dist/')) {
76
150
  return;
77
151
  }
78
- if (path.endsWith('.html') || path.endsWith('.ts') || path.endsWith('.md')) {
79
- const initialContent = entry?.content.toString();
80
- let newContent = initialContent;
81
- if (newContent) {
82
- resolvedIconsReplacements.forEach(({ replace, replaceWith }) => {
83
- newContent = newContent.replace(new RegExp(replace, 'g'), replaceWith);
84
- });
85
- newContent = handleDeprecatedIcons(newContent, path);
86
- if (initialContent !== newContent) {
87
- tree.overwrite(path, newContent || '');
88
- }
89
- }
152
+ if (filePath.endsWith('.html')) {
153
+ templatePaths.push(filePath);
154
+ }
155
+ else if (filePath.endsWith('.ts') &&
156
+ !filePath.endsWith('.d.ts') &&
157
+ !filePath.endsWith('.ngtypecheck.ts')) {
158
+ tsPaths.push(filePath);
159
+ }
160
+ else if (filePath.endsWith('.md')) {
161
+ markdownPaths.push(filePath);
90
162
  }
91
163
  });
92
- // update styles
93
- targetDir.visit((path, entry) => {
94
- // if project property not provided, provide node_modules to be changed
95
- if (path.includes('node_modules')) {
164
+ await utils_angularParsing.migrateTemplateWithTransform(tree, templatePaths, context, utils_iconMigration.createIconTemplateTransform(migrationData, tokenMap, { fix, onFound, warn }));
165
+ await utils_iconMigration.migrateIconsInTsFiles(tree, tsPaths, context, migrationData, tokenMap, { fix, onFound, warn }, tsInlineStylePatterns);
166
+ // Markdown docs have no AST here, so like styles — they're matched with the same
167
+ // word/selector-boundary-safe, known-token-only regex rather than an unscoped replace.
168
+ for (const filePath of markdownPaths) {
169
+ const initialContent = tree.read(filePath)?.toString();
170
+ if (!initialContent) {
171
+ continue;
172
+ }
173
+ const { content, changed, found } = utils_iconMigration.replaceKnownIconTokens(initialContent, stylePatterns, fix);
174
+ if (found.length && !fix) {
175
+ onFound(filePath, found);
176
+ }
177
+ if (changed) {
178
+ tree.overwrite(filePath, content);
179
+ }
180
+ }
181
+ // update styles — icon-name renames always apply; `updatePrefix` only adds the bare
182
+ // scope-word rename (see `styleAndMarkdownTokenMap` above).
183
+ targetDir.visit((filePath) => {
184
+ // if project property not provided, styles in node_modules are still skipped, same as
185
+ // every other file type above
186
+ if (filePath.includes('node_modules')) {
187
+ return;
188
+ }
189
+ if (!filePath.endsWith(stylesExt)) {
96
190
  return;
97
191
  }
98
- if (path.endsWith(stylesExt)) {
99
- const initialContent = entry?.content.toString();
100
- let newContent = initialContent;
101
- if (newContent) {
102
- // replace icons in styles
103
- if (updatePrefix) {
104
- newContent = newContent.replace(new RegExp('mc-', 'g'), 'kbq-');
105
- }
106
- newContent = handleDeprecatedIcons(newContent, path);
107
- }
108
- if (initialContent !== newContent) {
109
- tree.overwrite(path, newContent || '');
110
- }
192
+ const initialContent = tree.read(filePath)?.toString();
193
+ if (!initialContent) {
194
+ return;
195
+ }
196
+ const { content, changed, found } = utils_iconMigration.replaceKnownIconTokens(initialContent, stylePatterns, fix);
197
+ if (found.length && !fix) {
198
+ onFound(filePath, found);
199
+ }
200
+ if (changed) {
201
+ tree.overwrite(filePath, content);
111
202
  }
112
203
  });
113
204
  };
@@ -7,9 +7,19 @@
7
7
  "factory": "./migrations/v20-upgrade/index"
8
8
  },
9
9
  "filter-bar-signals": {
10
- "version": "21.0.0-0",
10
+ "version": "20.2.0-0",
11
11
  "description": "Migrates KbqFilterBar consumers to the signal-based API. Rewrites programmatic reads of the now-signal members (filter, pipeTemplates, isChanged, isDisabled, isReadOnly, isSaved, isSavedAndChanged) to calls and `filter = v` writes to `filter.set(v)` on receivers typed KbqFilterBar, including reads via template reference variables on <kbq-filter-bar>. Renames KbqFilterBarRefresher → KbqFilterRefresher and warns on changes/preparePopover/view-query cases that need manual migration.",
12
12
  "factory": "./migrations/filter-bar-signals/index"
13
+ },
14
+ "alert-signals": {
15
+ "version": "20.2.0-0",
16
+ "description": "Migrates KbqAlert consumers to its finished signal-based API. Rewrites value-safe programmatic reads of the now-signal members (compact, alertStyle) to calls on receivers typed KbqAlert, including reads via template reference variables on <kbq-alert> (external and inline templates). Warns — without auto-fixing — on alertColor (now a read-only InputSignal whose getter returns the raw color instead of the `kbq-alert_<color>` class), the content-query members that became protected (icon/iconItem/button/title/control/closeButton/isColored), narrowed alertColor/alertStyle inputs, the compact booleanAttribute behavior change, descendants:false content projection, view/content queries returning the instance, and KbqAlertModule no longer re-exporting A11yModule/PlatformModule.",
17
+ "factory": "./migrations/alert-signals/index"
18
+ },
19
+ "autocomplete-panel-width-auto": {
20
+ "version": "20.2.0-0",
21
+ "description": "Replaces `panelWidth=\"auto\"` with `panelWidth=\"fit-content\"` on `<kbq-autocomplete>`. `auto` used to be passed to CSS verbatim, so the panel shrank to fit its content; it now means \"match the host width\", matching `kbq-select` and `kbq-tree-select`. The change is silent — `auto` still type-checks and still renders — so unmigrated templates only lay out differently.",
22
+ "factory": "./migrations/autocomplete-panel-width-auto/index"
13
23
  }
14
24
  }
15
25
  }
@@ -27,11 +27,11 @@ function ngAdd(options) {
27
27
  }
28
28
  // Installing dependencies
29
29
  utils_packageConfig.addPackageToPackageJson(tree, '@angular/cdk', "^20.2.14");
30
- utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/angular-luxon-adapter', "^20.1.0");
30
+ utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/angular-luxon-adapter', "^20.3.0");
31
31
  utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/date-formatter', "^3.5.1");
32
32
  utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/date-adapter', "^3.5.1");
33
- utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/icons', "^11.7.1");
34
- utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/design-tokens', "^3.17.2");
33
+ utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/icons', "^12.2.0");
34
+ utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/design-tokens', "^3.19.0");
35
35
  utils_packageConfig.addPackageToPackageJson(tree, 'luxon', "^3.7.2");
36
36
  };
37
37
  }