@koobiq/components 21.0.0 → 21.0.1

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 (222) hide show
  1. package/fesm2022/koobiq-components-code-block.mjs +45 -17
  2. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  3. package/fesm2022/koobiq-components-core.mjs +1 -1
  4. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  5. package/fesm2022/koobiq-components-filter-bar.mjs +9 -5
  6. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  7. package/fesm2022/koobiq-components-icon.mjs +37 -16
  8. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  9. package/fesm2022/koobiq-components-tree-select.mjs +20 -5
  10. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  11. package/fesm2022/koobiq-components-tree.mjs +218 -83
  12. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  13. package/package.json +3 -3
  14. package/schematics/collection.json +94 -89
  15. package/schematics/migrations/accordion-state-saving-default/{index.js → index.cjs} +5 -4
  16. package/schematics/migrations/actions-panel-overlay-container/{index.js → index.cjs} +5 -4
  17. package/schematics/migrations/alert-signals/{index.js → index.cjs} +14 -13
  18. package/schematics/migrations/angular-animations-removal/index.cjs +21 -0
  19. package/schematics/migrations/app-switcher-signals/{index.js → index.cjs} +7 -6
  20. package/schematics/migrations/autocomplete-panel-width-auto/{index.js → index.cjs} +6 -5
  21. package/schematics/migrations/autocomplete-signals/{index.js → index.cjs} +7 -6
  22. package/schematics/migrations/badge-signals/{index.js → index.cjs} +7 -6
  23. package/schematics/migrations/button-state-and-styles/{index.js → index.cjs} +7 -6
  24. package/schematics/migrations/button-supported-colors/{index.js → index.cjs} +7 -6
  25. package/schematics/migrations/button-toggle-signals-and-aria/{index.js → index.cjs} +7 -6
  26. package/schematics/migrations/button-truncation/{index.js → index.cjs} +7 -6
  27. package/schematics/migrations/checkbox-signals/{index.js → index.cjs} +9 -8
  28. package/schematics/migrations/clamped-text-disclosure/{index.js → index.cjs} +5 -4
  29. package/schematics/migrations/code-block-highlight-js-core/README.md +53 -0
  30. package/schematics/migrations/code-block-highlight-js-core/data.cjs +64 -0
  31. package/schematics/migrations/code-block-highlight-js-core/index.cjs +319 -0
  32. package/schematics/migrations/code-block-highlight-js-core/schema.json +20 -0
  33. package/schematics/migrations/code-block-signals/{index.js → index.cjs} +7 -6
  34. package/schematics/migrations/color-signals/index.cjs +20 -0
  35. package/schematics/migrations/core-mixins-removal/index.cjs +18 -0
  36. package/schematics/migrations/css-selectors/{index.js → index.cjs} +4 -3
  37. package/schematics/migrations/datepicker-signals/index.cjs +18 -0
  38. package/schematics/migrations/deprecated-icons/{index.js → index.cjs} +8 -7
  39. package/schematics/migrations/design-tokens-v4/{index.js → index.cjs} +3 -2
  40. package/schematics/migrations/divider-signals-and-aria/{index.js → index.cjs} +5 -4
  41. package/schematics/migrations/dl-attribute-coercion/{index.js → index.cjs} +7 -6
  42. package/schematics/migrations/dl-standalone-names/{index.js → index.cjs} +11 -10
  43. package/schematics/migrations/dropdown-demote-overlay/{index.js → index.cjs} +7 -6
  44. package/schematics/migrations/dropdown-signals/index.cjs +20 -0
  45. package/schematics/migrations/empty-state-error-color/{index.js → index.cjs} +5 -4
  46. package/schematics/migrations/empty-state-size-attr/{index.js → index.cjs} +6 -5
  47. package/schematics/migrations/file-upload-cva-and-primitives/{index.js → index.cjs} +5 -4
  48. package/schematics/migrations/file-upload-deprecated-outputs/{index.js → index.cjs} +5 -4
  49. package/schematics/migrations/filter-bar-rename-action/{index.js → index.cjs} +5 -4
  50. package/schematics/migrations/filter-bar-signals/{index.js → index.cjs} +16 -15
  51. package/schematics/migrations/filter-bar-state-saving-default/{index.js → index.cjs} +5 -4
  52. package/schematics/migrations/flag-inner-html/{index.js → index.cjs} +5 -4
  53. package/schematics/migrations/form-field-signals/{index.js → index.cjs} +18 -17
  54. package/schematics/migrations/icon-semantics-and-api/{data.js → data.cjs} +4 -4
  55. package/schematics/migrations/icon-semantics-and-api/{index.js → index.cjs} +6 -5
  56. package/schematics/migrations/icons-replacement/{index.js → index.cjs} +4 -3
  57. package/schematics/migrations/inline-edit-a11y-and-types/{index.js → index.cjs} +5 -4
  58. package/schematics/migrations/input-number-surface/{index.js → index.cjs} +5 -4
  59. package/schematics/migrations/input-signals/index.cjs +18 -0
  60. package/schematics/migrations/link-deprecated-path/{index.js → index.cjs} +4 -3
  61. package/schematics/migrations/link-signals/{index.js → index.cjs} +5 -4
  62. package/schematics/migrations/list-signals/index.cjs +18 -0
  63. package/schematics/migrations/list-tree-multiple-input/{index.js → index.cjs} +7 -6
  64. package/schematics/migrations/loader-overlay-signals/{index.js → index.cjs} +7 -6
  65. package/schematics/migrations/loader-overlay-size-attr/{index.js → index.cjs} +6 -5
  66. package/schematics/migrations/locale-configuration-providers/{index.js → index.cjs} +5 -4
  67. package/schematics/migrations/mandatory-peer-dependencies/{index.js → index.cjs} +3 -2
  68. package/schematics/migrations/markdown-signals/{index.js → index.cjs} +7 -6
  69. package/schematics/migrations/modal-dialog-semantics/{index.js → index.cjs} +5 -4
  70. package/schematics/migrations/modal-signals/index.cjs +20 -0
  71. package/schematics/migrations/navbar-signals-and-aria/{index.js → index.cjs} +7 -6
  72. package/schematics/migrations/new-icons-pack/{index.js → index.cjs} +8 -7
  73. package/schematics/migrations/notification-center-signals/{index.js → index.cjs} +5 -4
  74. package/schematics/migrations/option-signals/index.cjs +20 -0
  75. package/schematics/migrations/popover-leave-delay/{index.js → index.cjs} +5 -4
  76. package/schematics/migrations/progress-bar-percentage-and-aria/{index.js → index.cjs} +5 -4
  77. package/schematics/migrations/progress-spinner-signals/{index.js → index.cjs} +7 -6
  78. package/schematics/migrations/query-list-signals/index.cjs +18 -0
  79. package/schematics/migrations/radio-signals-and-aria/{index.js → index.cjs} +9 -8
  80. package/schematics/migrations/read-state-dwell-handlers/{index.js → index.cjs} +5 -4
  81. package/schematics/migrations/scrollbar-deprecated-path/{index.js → index.cjs} +4 -3
  82. package/schematics/migrations/select-signal-inputs/{index.js → index.cjs} +5 -4
  83. package/schematics/migrations/sidepanel-non-modal-behavior/{index.js → index.cjs} +5 -4
  84. package/schematics/migrations/signal-inputs-subclasses/index.cjs +18 -0
  85. package/schematics/migrations/split-button-optional-disabled/{index.js → index.cjs} +5 -4
  86. package/schematics/migrations/splitter-deprecated-path/{index.js → index.cjs} +4 -3
  87. package/schematics/migrations/state-saving-default/{index.js → index.cjs} +5 -4
  88. package/schematics/migrations/table-cell-content/{index.js → index.cjs} +5 -4
  89. package/schematics/migrations/tabs-signals-and-aria/{index.js → index.cjs} +5 -4
  90. package/schematics/migrations/tag-list-cleaner/{index.js → index.cjs} +7 -6
  91. package/schematics/migrations/tag-slots/{index.js → index.cjs} +6 -5
  92. package/schematics/migrations/tags-signals/{index.js → index.cjs} +7 -6
  93. package/schematics/migrations/textarea-signals/{index.js → index.cjs} +7 -6
  94. package/schematics/migrations/time-range-title-for/{index.js → index.cjs} +5 -4
  95. package/schematics/migrations/timepicker-signals/{index.js → index.cjs} +7 -6
  96. package/schematics/migrations/timezone-grouping-utils/{index.js → index.cjs} +5 -4
  97. package/schematics/migrations/title-encapsulation/{index.js → index.cjs} +5 -4
  98. package/schematics/migrations/toast-stack-and-defaults/{index.js → index.cjs} +5 -4
  99. package/schematics/migrations/tooltip-pointer-events-and-types/{index.js → index.cjs} +5 -4
  100. package/schematics/migrations/top-bar-container-selectors/{index.js → index.cjs} +5 -4
  101. package/schematics/migrations/tree-select-signals/{index.js → index.cjs} +5 -4
  102. package/schematics/migrations/tree-signals/{index.js → index.cjs} +5 -4
  103. package/schematics/migrations/tree-state-saving-default/{index.js → index.cjs} +5 -4
  104. package/schematics/migrations/username-pipe-injection/{index.js → index.cjs} +5 -4
  105. package/schematics/migrations/v20-upgrade/{data.js → data.cjs} +7 -7
  106. package/schematics/migrations/v20-upgrade/index.cjs +19 -0
  107. package/schematics/migrations/v21-upgrade/{data.js → data.cjs} +22 -22
  108. package/schematics/migrations/v21-upgrade/{index.js → index.cjs} +11 -10
  109. package/schematics/migrations/zoneless-change-detection/index.cjs +21 -0
  110. package/schematics/migrations.json +87 -82
  111. package/schematics/ng-add/{index.js → index.cjs} +12 -286
  112. package/schematics/utils/{angular-parsing.js → angular-parsing.cjs} +2 -2
  113. package/schematics/utils/{deprecated-path-migration.js → deprecated-path-migration.cjs} +4 -3
  114. package/schematics/utils/html-config.cjs +148 -0
  115. package/schematics/utils/{icon-migration.js → icon-migration.cjs} +2 -2
  116. package/schematics/utils/list-item-pattern.cjs +16 -0
  117. package/schematics/utils/package-config.cjs +80 -0
  118. package/schematics/utils/project-files.cjs +25 -0
  119. package/schematics/utils/replacement-driver.cjs +337 -0
  120. package/schematics/utils/safe-rule.cjs +23 -0
  121. package/schematics/utils/signal-members-migration.cjs +779 -0
  122. package/schematics/utils/tag-patterns.cjs +21 -0
  123. package/schematics/utils/template-ref-access.cjs +155 -0
  124. package/schematics/utils/{typescript.js → typescript.cjs} +1 -1
  125. package/schematics/utils/warn-only-migration.cjs +52 -0
  126. package/schematics/utils/workspace-styles.cjs +123 -0
  127. package/types/koobiq-components-code-block.d.ts +38 -11
  128. package/types/koobiq-components-filter-bar.d.ts +2 -2
  129. package/types/koobiq-components-tree-select.d.ts +11 -8
  130. package/types/koobiq-components-tree.d.ts +108 -59
  131. package/schematics/migrations/angular-animations-removal/index.js +0 -20
  132. package/schematics/migrations/color-signals/index.js +0 -19
  133. package/schematics/migrations/core-mixins-removal/index.js +0 -17
  134. package/schematics/migrations/datepicker-signals/index.js +0 -17
  135. package/schematics/migrations/dropdown-signals/index.js +0 -19
  136. package/schematics/migrations/input-signals/index.js +0 -17
  137. package/schematics/migrations/list-signals/index.js +0 -17
  138. package/schematics/migrations/modal-signals/index.js +0 -19
  139. package/schematics/migrations/option-signals/index.js +0 -19
  140. package/schematics/migrations/query-list-signals/index.js +0 -17
  141. package/schematics/migrations/signal-inputs-subclasses/index.js +0 -17
  142. package/schematics/migrations/v20-upgrade/index.js +0 -18
  143. package/schematics/migrations/zoneless-change-detection/index.js +0 -20
  144. package/schematics/utils/package-config.js +0 -13
  145. /package/schematics/migrations/accordion-state-saving-default/{data.js → data.cjs} +0 -0
  146. /package/schematics/migrations/actions-panel-overlay-container/{data.js → data.cjs} +0 -0
  147. /package/schematics/migrations/alert-signals/{data.js → data.cjs} +0 -0
  148. /package/schematics/migrations/angular-animations-removal/{data.js → data.cjs} +0 -0
  149. /package/schematics/migrations/app-switcher-signals/{data.js → data.cjs} +0 -0
  150. /package/schematics/migrations/autocomplete-signals/{data.js → data.cjs} +0 -0
  151. /package/schematics/migrations/badge-signals/{data.js → data.cjs} +0 -0
  152. /package/schematics/migrations/button-state-and-styles/{data.js → data.cjs} +0 -0
  153. /package/schematics/migrations/button-supported-colors/{data.js → data.cjs} +0 -0
  154. /package/schematics/migrations/button-toggle-signals-and-aria/{data.js → data.cjs} +0 -0
  155. /package/schematics/migrations/button-truncation/{data.js → data.cjs} +0 -0
  156. /package/schematics/migrations/checkbox-signals/{data.js → data.cjs} +0 -0
  157. /package/schematics/migrations/clamped-text-disclosure/{data.js → data.cjs} +0 -0
  158. /package/schematics/migrations/code-block-signals/{data.js → data.cjs} +0 -0
  159. /package/schematics/migrations/color-signals/{data.js → data.cjs} +0 -0
  160. /package/schematics/migrations/core-mixins-removal/{data.js → data.cjs} +0 -0
  161. /package/schematics/migrations/css-selectors/{data.js → data.cjs} +0 -0
  162. /package/schematics/migrations/datepicker-signals/{data.js → data.cjs} +0 -0
  163. /package/schematics/migrations/deprecated-icons/{data.js → data.cjs} +0 -0
  164. /package/schematics/migrations/divider-signals-and-aria/{data.js → data.cjs} +0 -0
  165. /package/schematics/migrations/dl-attribute-coercion/{data.js → data.cjs} +0 -0
  166. /package/schematics/migrations/dl-standalone-names/{data.js → data.cjs} +0 -0
  167. /package/schematics/migrations/dropdown-demote-overlay/{data.js → data.cjs} +0 -0
  168. /package/schematics/migrations/dropdown-signals/{data.js → data.cjs} +0 -0
  169. /package/schematics/migrations/empty-state-error-color/{data.js → data.cjs} +0 -0
  170. /package/schematics/migrations/file-upload-cva-and-primitives/{data.js → data.cjs} +0 -0
  171. /package/schematics/migrations/file-upload-deprecated-outputs/{data.js → data.cjs} +0 -0
  172. /package/schematics/migrations/filter-bar-rename-action/{data.js → data.cjs} +0 -0
  173. /package/schematics/migrations/filter-bar-signals/{data.js → data.cjs} +0 -0
  174. /package/schematics/migrations/filter-bar-state-saving-default/{data.js → data.cjs} +0 -0
  175. /package/schematics/migrations/flag-inner-html/{data.js → data.cjs} +0 -0
  176. /package/schematics/migrations/form-field-signals/{data.js → data.cjs} +0 -0
  177. /package/schematics/migrations/icons-replacement/{data.js → data.cjs} +0 -0
  178. /package/schematics/migrations/inline-edit-a11y-and-types/{data.js → data.cjs} +0 -0
  179. /package/schematics/migrations/input-number-surface/{data.js → data.cjs} +0 -0
  180. /package/schematics/migrations/input-signals/{data.js → data.cjs} +0 -0
  181. /package/schematics/migrations/link-signals/{data.js → data.cjs} +0 -0
  182. /package/schematics/migrations/list-signals/{data.js → data.cjs} +0 -0
  183. /package/schematics/migrations/list-tree-multiple-input/{data.js → data.cjs} +0 -0
  184. /package/schematics/migrations/loader-overlay-signals/{data.js → data.cjs} +0 -0
  185. /package/schematics/migrations/locale-configuration-providers/{data.js → data.cjs} +0 -0
  186. /package/schematics/migrations/markdown-signals/{data.js → data.cjs} +0 -0
  187. /package/schematics/migrations/modal-dialog-semantics/{data.js → data.cjs} +0 -0
  188. /package/schematics/migrations/modal-signals/{data.js → data.cjs} +0 -0
  189. /package/schematics/migrations/navbar-signals-and-aria/{data.js → data.cjs} +0 -0
  190. /package/schematics/migrations/new-icons-pack/{data.js → data.cjs} +0 -0
  191. /package/schematics/migrations/notification-center-signals/{data.js → data.cjs} +0 -0
  192. /package/schematics/migrations/option-signals/{data.js → data.cjs} +0 -0
  193. /package/schematics/migrations/popover-leave-delay/{data.js → data.cjs} +0 -0
  194. /package/schematics/migrations/progress-bar-percentage-and-aria/{data.js → data.cjs} +0 -0
  195. /package/schematics/migrations/progress-spinner-signals/{data.js → data.cjs} +0 -0
  196. /package/schematics/migrations/query-list-signals/{data.js → data.cjs} +0 -0
  197. /package/schematics/migrations/radio-signals-and-aria/{data.js → data.cjs} +0 -0
  198. /package/schematics/migrations/read-state-dwell-handlers/{data.js → data.cjs} +0 -0
  199. /package/schematics/migrations/select-signal-inputs/{data.js → data.cjs} +0 -0
  200. /package/schematics/migrations/sidepanel-non-modal-behavior/{data.js → data.cjs} +0 -0
  201. /package/schematics/migrations/signal-inputs-subclasses/{data.js → data.cjs} +0 -0
  202. /package/schematics/migrations/split-button-optional-disabled/{data.js → data.cjs} +0 -0
  203. /package/schematics/migrations/state-saving-default/{data.js → data.cjs} +0 -0
  204. /package/schematics/migrations/table-cell-content/{data.js → data.cjs} +0 -0
  205. /package/schematics/migrations/tabs-signals-and-aria/{data.js → data.cjs} +0 -0
  206. /package/schematics/migrations/tag-list-cleaner/{data.js → data.cjs} +0 -0
  207. /package/schematics/migrations/tags-signals/{data.js → data.cjs} +0 -0
  208. /package/schematics/migrations/textarea-signals/{data.js → data.cjs} +0 -0
  209. /package/schematics/migrations/time-range-title-for/{data.js → data.cjs} +0 -0
  210. /package/schematics/migrations/timepicker-signals/{data.js → data.cjs} +0 -0
  211. /package/schematics/migrations/timezone-grouping-utils/{data.js → data.cjs} +0 -0
  212. /package/schematics/migrations/title-encapsulation/{data.js → data.cjs} +0 -0
  213. /package/schematics/migrations/toast-stack-and-defaults/{data.js → data.cjs} +0 -0
  214. /package/schematics/migrations/tooltip-pointer-events-and-types/{data.js → data.cjs} +0 -0
  215. /package/schematics/migrations/top-bar-container-selectors/{data.js → data.cjs} +0 -0
  216. /package/schematics/migrations/tree-select-signals/{data.js → data.cjs} +0 -0
  217. /package/schematics/migrations/tree-signals/{data.js → data.cjs} +0 -0
  218. /package/schematics/migrations/tree-state-saving-default/{data.js → data.cjs} +0 -0
  219. /package/schematics/migrations/username-pipe-injection/{data.js → data.cjs} +0 -0
  220. /package/schematics/migrations/zoneless-change-detection/{data.js → data.cjs} +0 -0
  221. /package/schematics/utils/{ast.js → ast.cjs} +0 -0
  222. /package/schematics/utils/{messages.js → messages.cjs} +0 -0
@@ -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;