@juspay/svelte-ui-components 3.5.0 → 3.5.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 (152) hide show
  1. package/README.md +1 -1
  2. package/dist/Accordion/Accordion.svelte +1 -5
  3. package/dist/Accordion/properties.d.ts +0 -1
  4. package/dist/AreaChart/AreaChart.svelte +2 -8
  5. package/dist/AreaChart/properties.d.ts +0 -10
  6. package/dist/AttachmentChipRow/AttachmentChipRow.svelte +30 -30
  7. package/dist/AttachmentChipRow/properties.d.ts +6 -6
  8. package/dist/Banner/Banner.svelte +1 -5
  9. package/dist/Banner/properties.d.ts +0 -1
  10. package/dist/BarChart/BarChart.svelte +7 -13
  11. package/dist/BarChart/properties.d.ts +1 -9
  12. package/dist/Book/Book.svelte +1 -5
  13. package/dist/Book/properties.d.ts +0 -1
  14. package/dist/Calendar/Calendar.svelte +3 -11
  15. package/dist/Calendar/properties.d.ts +0 -11
  16. package/dist/Chat/Chat.svelte +9 -29
  17. package/dist/Chat/properties.d.ts +0 -9
  18. package/dist/Chat/types.d.ts +7 -0
  19. package/dist/ChatBubble/ChatBubble.svelte +3 -11
  20. package/dist/ChatBubble/properties.d.ts +0 -3
  21. package/dist/ChatComposer/ChatComposer.svelte +18 -44
  22. package/dist/ChatComposer/properties.d.ts +0 -12
  23. package/dist/ChatHeader/ChatHeader.svelte +1 -5
  24. package/dist/ChatHeader/properties.d.ts +0 -1
  25. package/dist/ChatMessage/ChatMessage.svelte +87 -11
  26. package/dist/ChatMessage/properties.d.ts +18 -3
  27. package/dist/ChatMessageList/ChatMessageList.svelte +5 -11
  28. package/dist/ChatMessageList/properties.d.ts +0 -6
  29. package/dist/ChatSuggestions/ChatSuggestions.svelte +1 -5
  30. package/dist/ChatSuggestions/properties.d.ts +0 -1
  31. package/dist/CheckListItem/CheckListItem.svelte +1 -5
  32. package/dist/CheckListItem/properties.d.ts +0 -1
  33. package/dist/Checkbox/Checkbox.svelte +1 -5
  34. package/dist/Checkbox/properties.d.ts +0 -1
  35. package/dist/ChipInput/ChipInput.svelte +10 -20
  36. package/dist/ChipInput/properties.d.ts +0 -4
  37. package/dist/Choicebox/Choicebox.svelte +1 -5
  38. package/dist/Choicebox/properties.d.ts +0 -1
  39. package/dist/ColorPicker/ColorPicker.svelte +4 -10
  40. package/dist/ColorPicker/properties.d.ts +0 -2
  41. package/dist/Combobox/Combobox.svelte +15 -33
  42. package/dist/Combobox/properties.d.ts +0 -8
  43. package/dist/CommandMenu/CommandMenu.svelte +2 -8
  44. package/dist/CommandMenu/properties.d.ts +0 -2
  45. package/dist/ContextMenu/ContextMenu.svelte +3 -11
  46. package/dist/ContextMenu/properties.d.ts +0 -3
  47. package/dist/DateRangePicker/DateRangePicker.svelte +6 -20
  48. package/dist/DateRangePicker/properties.d.ts +0 -19
  49. package/dist/Draggable/Draggable.svelte +7 -7
  50. package/dist/Draggable/properties.d.ts +3 -3
  51. package/dist/DualAxisBarChart/DualAxisBarChart.svelte +1 -5
  52. package/dist/DualAxisBarChart/properties.d.ts +0 -4
  53. package/dist/FileDropzoneTrigger/FileDropzoneTrigger.svelte +1 -5
  54. package/dist/FileDropzoneTrigger/properties.d.ts +0 -1
  55. package/dist/FileInput/FileInput.svelte +2 -8
  56. package/dist/FileInput/properties.d.ts +0 -2
  57. package/dist/FunnelChart/FunnelChart.svelte +2 -8
  58. package/dist/FunnelChart/properties.d.ts +0 -8
  59. package/dist/Gallery/Gallery.svelte +15 -15
  60. package/dist/Gallery/properties.d.ts +6 -6
  61. package/dist/HITL/HITL.svelte +10 -8
  62. package/dist/HITL/properties.d.ts +2 -2
  63. package/dist/IframeViewer/IframeViewer.svelte +3 -2
  64. package/dist/IframeViewer/properties.d.ts +1 -1
  65. package/dist/Img/Img.svelte +119 -39
  66. package/dist/Img/properties.d.ts +0 -1
  67. package/dist/Input/Input.svelte +22 -37
  68. package/dist/Input/properties.d.ts +3 -10
  69. package/dist/InputButton/InputButton.svelte +2 -2
  70. package/dist/LineChart/LineChart.svelte +4 -10
  71. package/dist/LineChart/properties.d.ts +1 -11
  72. package/dist/ListItem/ListItem.svelte +10 -22
  73. package/dist/ListItem/properties.d.ts +5 -10
  74. package/dist/LottiePlayer/LottiePlayer.svelte +2 -8
  75. package/dist/LottiePlayer/properties.d.ts +0 -2
  76. package/dist/MediaPlayer/MediaPlayer.svelte +1 -5
  77. package/dist/MediaPlayer/properties.d.ts +0 -1
  78. package/dist/MediaUpload/MediaUpload.svelte +6 -6
  79. package/dist/MediaUpload/properties.d.ts +3 -3
  80. package/dist/Menu/Menu.svelte +3 -11
  81. package/dist/Menu/properties.d.ts +0 -3
  82. package/dist/Modal/Modal.svelte +15 -31
  83. package/dist/Modal/properties.d.ts +5 -11
  84. package/dist/Pagination/Pagination.svelte +3 -7
  85. package/dist/Pagination/properties.d.ts +1 -2
  86. package/dist/PieChart/PieChart.svelte +4 -10
  87. package/dist/PieChart/properties.d.ts +1 -9
  88. package/dist/Pill/Pill.svelte +1 -5
  89. package/dist/Pill/properties.d.ts +0 -1
  90. package/dist/Radio/Radio.svelte +1 -5
  91. package/dist/Radio/properties.d.ts +0 -1
  92. package/dist/Resizable/Resizable.svelte +3 -11
  93. package/dist/Resizable/properties.d.ts +0 -3
  94. package/dist/SankeyChart/SankeyChart.svelte +4 -14
  95. package/dist/SankeyChart/properties.d.ts +0 -12
  96. package/dist/Scroller/Scroller.svelte +1 -5
  97. package/dist/Scroller/properties.d.ts +0 -1
  98. package/dist/Select/Select.svelte +3 -11
  99. package/dist/Select/properties.d.ts +0 -3
  100. package/dist/Sheet/Sheet.svelte +3 -11
  101. package/dist/Sheet/properties.d.ts +0 -3
  102. package/dist/Slider/Slider.svelte +2 -8
  103. package/dist/Slider/properties.d.ts +0 -2
  104. package/dist/Snippet/Snippet.svelte +1 -5
  105. package/dist/Snippet/properties.d.ts +0 -1
  106. package/dist/SplitButton/SplitButton.svelte +1 -5
  107. package/dist/SplitButton/properties.d.ts +0 -1
  108. package/dist/SplitInput/SplitInput.svelte +6 -14
  109. package/dist/SplitInput/properties.d.ts +0 -3
  110. package/dist/StatCard/StatCard.svelte +2 -2
  111. package/dist/StatCard/properties.d.ts +1 -1
  112. package/dist/Status/Status.svelte +2 -6
  113. package/dist/Status/properties.d.ts +1 -2
  114. package/dist/Stepper/Stepper.svelte +2 -12
  115. package/dist/Stepper/properties.d.ts +1 -14
  116. package/dist/Table/BuiltinCell.svelte +1 -1
  117. package/dist/Table/Table.svelte +16 -17
  118. package/dist/Table/properties.d.ts +3 -35
  119. package/dist/Tabs/Tabs.svelte +2 -8
  120. package/dist/Tabs/properties.d.ts +0 -2
  121. package/dist/TaskList/TaskList.svelte +1 -4
  122. package/dist/TaskList/properties.d.ts +0 -1
  123. package/dist/ThemeSwitcher/ThemeSwitcher.svelte +1 -5
  124. package/dist/ThemeSwitcher/properties.d.ts +0 -1
  125. package/dist/ThinkingIndicator/ThinkingIndicator.svelte +4 -10
  126. package/dist/ThinkingIndicator/properties.d.ts +1 -3
  127. package/dist/Toast/Toast.svelte +2 -2
  128. package/dist/Toast/properties.d.ts +1 -1
  129. package/dist/Toggle/Toggle.svelte +1 -5
  130. package/dist/Toggle/properties.d.ts +0 -1
  131. package/dist/ToolCallLog/ToolCallLog.svelte +1 -10
  132. package/dist/ToolCallLog/properties.d.ts +0 -1
  133. package/dist/Toolbar/Toolbar.svelte +2 -6
  134. package/dist/Toolbar/properties.d.ts +1 -2
  135. package/dist/TypewriterText/TypewriterText.svelte +3 -3
  136. package/dist/TypewriterText/properties.d.ts +1 -1
  137. package/dist-codemod/bin.js +32 -0
  138. package/dist-codemod/cli.js +175 -0
  139. package/dist-codemod/legacy-pairs.js +228 -0
  140. package/dist-codemod/transform.js +278 -0
  141. package/dist-codemod/wc-children.js +66 -0
  142. package/dist-wc/index.js +4458 -5127
  143. package/package.json +9 -7
  144. package/scripts/postinstall.mjs +14 -12
  145. package/dist/deprecation.d.ts +0 -42
  146. package/dist/deprecation.js +0 -57
  147. package/scripts/codemod/README.md +0 -76
  148. package/scripts/codemod/cli.ts +0 -206
  149. package/scripts/codemod/map.ts +0 -118
  150. package/scripts/codemod/transform.ts +0 -549
  151. package/scripts/codemod/tsconfig.json +0 -15
  152. package/scripts/codemod/wc-children.ts +0 -75
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",
@@ -21,13 +21,14 @@
21
21
  "homepage": "https://github.com/juspay/svelte-ui-components",
22
22
  "scripts": {
23
23
  "dev": "vite dev --host",
24
- "build": "vite build && npm run build:wc && npm run package",
24
+ "build": "vite build && npm run build:wc && npm run build:codemod && npm run package",
25
25
  "build:wc": "vite build --config vite.config.wc.ts && echo 'export {};' > dist-wc/index.d.ts",
26
+ "build:codemod": "rm -rf dist-codemod && tsc -p scripts/codemod/tsconfig.build.json",
26
27
  "preview": "vite preview",
27
28
  "package": "svelte-kit sync && svelte-package && publint",
28
- "prepublishOnly": "npm run build:wc && npm run package",
29
+ "prepublishOnly": "npm run build:wc && npm run build:codemod && npm run package",
29
30
  "test": "npm run test:integration && npm run test:unit",
30
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && npm run check:codemod && npm run check:migrate && npm run check:wc-parity",
31
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && npm run check:wc && npm run check:codemod && npm run check:migrate && npm run check:wc-parity",
31
32
  "check:codemod": "tsc -p scripts/codemod/tsconfig.json",
32
33
  "codemod": "node scripts/codemod/cli.ts",
33
34
  "check:wc": "svelte-check --tsconfig ./tsconfig.wc.json --compiler-warnings \"options_missing_custom_element:ignore\"",
@@ -59,8 +60,7 @@
59
60
  "!dist/**/*.test.*",
60
61
  "!dist/**/*.spec.*",
61
62
  "dist-wc",
62
- "scripts/codemod",
63
- "!scripts/codemod/*.test.ts",
63
+ "dist-codemod",
64
64
  "scripts/postinstall.mjs"
65
65
  ],
66
66
  "peerDependencies": {
@@ -92,6 +92,7 @@
92
92
  "@sveltejs/kit": "^2.63.1",
93
93
  "@sveltejs/package": "^2.5.8",
94
94
  "@sveltejs/vite-plugin-svelte": "^7.1.2",
95
+ "@testing-library/svelte": "^5.4.2",
95
96
  "@types/node": "^22.20.1",
96
97
  "@types/semver": "^7.8.0",
97
98
  "@typescript-eslint/eslint-plugin": "^8.60.1",
@@ -102,6 +103,7 @@
102
103
  "eslint-plugin-unused-imports": "^4.4.1",
103
104
  "globals": "^17.6.0",
104
105
  "husky": "^9.1.7",
106
+ "jsdom": "^29.1.1",
105
107
  "lottie-web": "^5.13.0",
106
108
  "marked": "^18.0.5",
107
109
  "prettier": "^3.8.3",
@@ -194,7 +196,7 @@
194
196
  }
195
197
  },
196
198
  "bin": {
197
- "sui-codemod": "./scripts/codemod/cli.ts"
199
+ "sui-codemod": "./dist-codemod/bin.js"
198
200
  },
199
201
  "engines": {
200
202
  "node": ">=22.18"
@@ -27,23 +27,25 @@ const isNonInteractive = () =>
27
27
  const notice = () =>
28
28
  [
29
29
  '',
30
- `${BOLD}@juspay/svelte-ui-components — one breaking change is coming in 4.0.0${RESET}`,
30
+ `${BOLD}@juspay/svelte-ui-components — two breaking changes are coming in 4.0.0${RESET}`,
31
31
  '',
32
- ' Nothing has changed yet. In 4.0.0, `children` stops being a settable',
33
- ' property on sui-chat-bubble, sui-draggable and sui-resizable, and',
34
- ' assigning it will silently lose the content.',
32
+ ' Nothing has changed yet. Both work today; both go away in 4.0.0:',
35
33
  '',
36
- ' Move to light-DOM children ahead of time:',
37
- ` ${DIM}el.children = snippet;${RESET} // before`,
38
- ` ${DIM}<sui-draggable><div>…</div></sui-draggable>${RESET} // after`,
34
+ ' 1. Every event prop is now lowercase (`onRowClick` -> `onrowclick`,',
35
+ ' `onClick` -> `onclick`), matching one rule for native and invented',
36
+ ' events alike. The 191 earlier spellings still work and warn once per',
37
+ ' prop in dev builds; 4.0.0 removes them.',
38
+ ' Plan: docs/EVENT_CASING_MIGRATION.md in the repository.',
39
39
  '',
40
- ' That change is what restores `element.children` on those three:',
41
- ' declaring the prop leaves it undefined today.',
40
+ ' 2. `children` stops being a settable property on sui-chat-bubble,',
41
+ ' sui-draggable and sui-resizable; assigning it will silently lose',
42
+ ' the content. Move to light-DOM children ahead of time:',
43
+ ` ${DIM}el.children = snippet;${RESET} // before`,
44
+ ` ${DIM}<sui-draggable><div>…</div></sui-draggable>${RESET} // after`,
42
45
  '',
43
- ` Find affected call sites now (reports only, writes nothing):`,
46
+ ' One command reports every affected call site (writes nothing), and',
47
+ ' rewrites the event props for you without --dry-run:',
44
48
  ` ${BOLD}npx sui-codemod --dry-run ./src${RESET}`,
45
- '',
46
- ` ${DIM}Nothing else in the custom-element surface breaks.${RESET}`,
47
49
  ''
48
50
  ].join('\n');
49
51
 
@@ -1,42 +0,0 @@
1
- /**
2
- * Phase 2 of `docs/EVENT_CASING_MIGRATION.md`: tell a consumer, once, that a
3
- * prop spelling is going away and what replaces it.
4
- *
5
- * Two constraints shape this.
6
- *
7
- * It is dev-only. A production warning is noise a consumer cannot act on
8
- * mid-incident, and 142 props warning in a production console would bury real
9
- * output. `import.meta.env.DEV` is the guard because it is what the bundler
10
- * this library is built with statically replaces, so the whole call is removed
11
- * from a production build rather than merely skipped at runtime.
12
- *
13
- * It warns once per component-and-prop, not once per render. A deprecated prop
14
- * on a list row would otherwise warn on every one of a thousand rows, and a
15
- * consumer would learn less from a thousand identical lines than from one.
16
- *
17
- * Internal. Nothing here is re-exported from `src/lib/index.ts`, because a
18
- * consumer has no call for it: the components invoke it themselves when they
19
- * are handed a deprecated spelling. That is this library's normal way of
20
- * marking a module internal rather than an omission -- `src/lib/utils.ts`
21
- * exports ten functions and the barrel re-exports three, leaving
22
- * `getStorageItem`, `hexToRgb` and five others reachable only from inside.
23
- * Exporting these two would add public API that 4.0.0 then has to keep.
24
- */
25
- /**
26
- * The release that removes the old spellings, named in one place so the message
27
- * and the migration plan cannot drift apart.
28
- *
29
- * 4.0.0 is a commitment, not a placeholder. An earlier draft of this string was
30
- * written while #506 was expected to cut the major; it shipped inside 3.2.0 as
31
- * a minor instead, which briefly left this warning promising a version nothing
32
- * was committed to. `docs/EVENT_CASING_MIGRATION.md` holds the plan; a test
33
- * pins this value so moving it is a deliberate edit and not a silent one.
34
- */
35
- export declare const DEPRECATION_REMOVAL_VERSION = "4.0.0";
36
- /**
37
- * Exposed for tests. A module-level Set survives between test cases, so a
38
- * second case asserting "warns once" would pass vacuously by inheriting the
39
- * first case's suppression rather than by exercising it.
40
- */
41
- export declare const resetDeprecationWarnings: () => void;
42
- export declare const warnDeprecatedProp: (component: string, oldName: string, newName: string) => void;
@@ -1,57 +0,0 @@
1
- /**
2
- * Phase 2 of `docs/EVENT_CASING_MIGRATION.md`: tell a consumer, once, that a
3
- * prop spelling is going away and what replaces it.
4
- *
5
- * Two constraints shape this.
6
- *
7
- * It is dev-only. A production warning is noise a consumer cannot act on
8
- * mid-incident, and 142 props warning in a production console would bury real
9
- * output. `import.meta.env.DEV` is the guard because it is what the bundler
10
- * this library is built with statically replaces, so the whole call is removed
11
- * from a production build rather than merely skipped at runtime.
12
- *
13
- * It warns once per component-and-prop, not once per render. A deprecated prop
14
- * on a list row would otherwise warn on every one of a thousand rows, and a
15
- * consumer would learn less from a thousand identical lines than from one.
16
- *
17
- * Internal. Nothing here is re-exported from `src/lib/index.ts`, because a
18
- * consumer has no call for it: the components invoke it themselves when they
19
- * are handed a deprecated spelling. That is this library's normal way of
20
- * marking a module internal rather than an omission -- `src/lib/utils.ts`
21
- * exports ten functions and the barrel re-exports three, leaving
22
- * `getStorageItem`, `hexToRgb` and five others reachable only from inside.
23
- * Exporting these two would add public API that 4.0.0 then has to keep.
24
- */
25
- /**
26
- * The release that removes the old spellings, named in one place so the message
27
- * and the migration plan cannot drift apart.
28
- *
29
- * 4.0.0 is a commitment, not a placeholder. An earlier draft of this string was
30
- * written while #506 was expected to cut the major; it shipped inside 3.2.0 as
31
- * a minor instead, which briefly left this warning promising a version nothing
32
- * was committed to. `docs/EVENT_CASING_MIGRATION.md` holds the plan; a test
33
- * pins this value so moving it is a deliberate edit and not a silent one.
34
- */
35
- export const DEPRECATION_REMOVAL_VERSION = '4.0.0';
36
- const seen = new Set();
37
- /**
38
- * Exposed for tests. A module-level Set survives between test cases, so a
39
- * second case asserting "warns once" would pass vacuously by inheriting the
40
- * first case's suppression rather than by exercising it.
41
- */
42
- export const resetDeprecationWarnings = () => {
43
- seen.clear();
44
- };
45
- export const warnDeprecatedProp = (component, oldName, newName) => {
46
- if (import.meta.env.DEV !== true) {
47
- return;
48
- }
49
- const key = `${component}.${oldName}`;
50
- if (seen.has(key)) {
51
- return;
52
- }
53
- seen.add(key);
54
- console.warn(`[svelte-ui-components] \`${oldName}\` on <${component}> is deprecated and will be ` +
55
- `removed in ${DEPRECATION_REMOVAL_VERSION}. Use \`${newName}\` instead — both work today. ` +
56
- `Run \`npx sui-codemod --dry-run ./src\` to see every affected call site.`);
57
- };
@@ -1,76 +0,0 @@
1
- # polymorph → SUI consumer migration codemod
2
-
3
- Also reports the one breaking change in the 4.0.0 custom-element surface:
4
- `children` is no longer a declared property on `sui-chat-bubble`,
5
- `sui-draggable` or `sui-resizable`, so assigning it silently loses the content.
6
- That check runs on every forward migration and in dry runs, reports rather than
7
- rewrites (moving content into markup is a decision, not a rename), and only
8
- fires in files that also mention one of the three elements. See
9
- `wc-children.ts`.
10
-
11
- This package is published, so consumers can run it without a checkout:
12
-
13
- ```sh
14
- npx sui-codemod --dry-run ./src
15
- ```
16
-
17
- Mechanically migrates a consumer codebase from `polymorph-ui-components` to
18
- `@juspay/svelte-ui-components`:
19
-
20
- - rewrites import/export/dynamic-import specifiers (subpaths like `/wc` are
21
- preserved), in `.svelte`, `.ts` and `.js` files;
22
- - renames the 28 synthetic event props (see `map.ts`) on library components in
23
- `.svelte` markup. All but one differ from the fork only in case; Stepper's
24
- `onhandlestepclick` becomes `onstepclick`, stepping over the deprecated
25
- `onhandleStepClick` alias that the casing match would otherwise have picked.
26
- Renaming is component-aware: `onsort` is renamed on a
27
- `<Table>` imported from the library (through aliases,
28
- `import { Table as DataTable }`, namespace imports and
29
- `<svelte:component this={Table}>`), and left alone on your own components
30
- and on native elements.
31
-
32
- ## Usage
33
-
34
- Run from a checkout of this repo (dependencies resolve here), pointing at the
35
- consumer project. Requires Node >= 22.18 (runs TypeScript directly).
36
-
37
- ```sh
38
- # preview
39
- npm run codemod -- --dry-run ../consumer-app/src
40
-
41
- # apply
42
- npm run codemod -- ../consumer-app/src
43
-
44
- # migrate in the other direction (SUI -> polymorph)
45
- npm run codemod -- --reverse ../consumer-app/src
46
- ```
47
-
48
- Directories are walked recursively; `node_modules`, `.git`, `.svelte-kit`,
49
- `dist`, `dist-wc`, `build`, `coverage`, `playwright-report` and `test-results`
50
- are skipped.
51
-
52
- ## What it will not do (by design)
53
-
54
- Anything it cannot prove safe is reported as a `WARN` with `file:line:column`
55
- instead of being rewritten — silent wrong rewrites are worse than reported
56
- skips:
57
-
58
- - **Spread attributes.** `<Table {...props} />` may carry a renamed prop
59
- inside `props`; the object is defined elsewhere, so it is warned about, not
60
- rewritten.
61
- - **Unresolvable components.** `const Picked = Table;` then
62
- `<Picked onsort={...} />` — the tag does not resolve to an import, so a
63
- warning is emitted when it carries a renameable prop name.
64
- - **Default imports** from the library cannot be resolved to a component.
65
- - **Semantic renames** — same event, different word — are not casing pairs
66
- and need a human: Gallery `onclose`→`onDismiss`, `onchange`→`onIndexChange`;
67
- MediaUpload `onchange`→`onFilesChange`, `onerror`→`onRejected`.
68
- - Props typed against library types in `<script>` (e.g. an object literal fed
69
- to a spread) are not rewritten — the spread warning covers the usage site.
70
-
71
- Shorthand attributes are expanded when renamed (`{onsort}` →
72
- `onSort={onsort}`), so a `--reverse` round trip restores the original names
73
- but not the shorthand form.
74
-
75
- `map.ts` documents how the pair list was derived and verified against both
76
- libraries' sources.
@@ -1,206 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
- import { join, resolve } from 'node:path';
3
- import { pathToFileURL } from 'node:url';
4
- import { parseArgs } from 'node:util';
5
- import type { Direction } from './map.ts';
6
- import { transformModuleSpecifiers, transformSvelte } from './transform.ts';
7
- import type { TransformResult } from './transform.ts';
8
- import { findChildrenAssignments } from './wc-children.ts';
9
-
10
- export type CliSummary = {
11
- readonly exitCode: number;
12
- readonly filesScanned: number;
13
- readonly filesChanged: number;
14
- readonly propsRenamed: number;
15
- readonly importsRewritten: number;
16
- readonly warnings: number;
17
- };
18
-
19
- const USAGE = [
20
- 'Usage: node scripts/codemod/cli.ts [--reverse] [--dry-run] <path...>',
21
- '',
22
- 'Migrates consumer sources from polymorph-ui-components to',
23
- '@juspay/svelte-ui-components: rewrites import specifiers and renames the',
24
- 'casing-only synthetic event props on library components (see map.ts).',
25
- '',
26
- ' --reverse migrate @juspay/svelte-ui-components -> polymorph-ui-components',
27
- ' --dry-run print every change as a diff without writing any file',
28
- ' --help show this help',
29
- '',
30
- 'Paths may be files or directories; directories are walked recursively,',
31
- 'skipping node_modules, .git, .svelte-kit, dist, dist-wc, build, coverage,',
32
- 'playwright-report and test-results.'
33
- ].join('\n');
34
-
35
- const SKIPPED_DIRECTORIES = new Set([
36
- 'node_modules',
37
- '.git',
38
- '.svelte-kit',
39
- 'dist',
40
- 'dist-wc',
41
- 'build',
42
- 'coverage',
43
- 'playwright-report',
44
- 'test-results'
45
- ]);
46
-
47
- const SCRIPT_FILE = /\.(ts|js|mts|mjs|cts|cjs)$/;
48
-
49
- function collectFiles(path: string, out: Set<string>): void {
50
- const stats = statSync(path);
51
- if (stats.isFile()) {
52
- if (path.endsWith('.svelte') || SCRIPT_FILE.test(path)) {
53
- out.add(path);
54
- }
55
- return;
56
- }
57
- if (!stats.isDirectory()) {
58
- return;
59
- }
60
- const entries = [...readdirSync(path, { withFileTypes: true })].sort((a, b) =>
61
- a.name.localeCompare(b.name)
62
- );
63
- for (const entry of entries) {
64
- if (entry.isDirectory()) {
65
- if (!SKIPPED_DIRECTORIES.has(entry.name)) {
66
- collectFiles(join(path, entry.name), out);
67
- }
68
- } else if (entry.isFile()) {
69
- collectFiles(join(path, entry.name), out);
70
- }
71
- }
72
- }
73
-
74
- /**
75
- * Every edit the transform makes stays on a single line, so old and new text
76
- * always have the same line count and a pairwise comparison is an exact diff.
77
- */
78
- function printLineDiff(
79
- file: string,
80
- before: string,
81
- after: string,
82
- log: (line: string) => void
83
- ): void {
84
- const oldLines = before.split('\n');
85
- const newLines = after.split('\n');
86
- log(`--- ${file}`);
87
- if (oldLines.length !== newLines.length) {
88
- log(' (line counts differ; showing full replacement)');
89
- for (const line of oldLines) {
90
- log(`- ${line}`);
91
- }
92
- for (const line of newLines) {
93
- log(`+ ${line}`);
94
- }
95
- return;
96
- }
97
- oldLines.forEach((oldLine, index) => {
98
- const newLine = newLines.at(index) ?? '';
99
- if (oldLine !== newLine) {
100
- log(`@@ ${file}:${index + 1}`);
101
- log(`- ${oldLine}`);
102
- log(`+ ${newLine}`);
103
- }
104
- });
105
- }
106
-
107
- export function runCodemod(argv: ReadonlyArray<string>, log: (line: string) => void): CliSummary {
108
- const failure = {
109
- exitCode: 2,
110
- filesScanned: 0,
111
- filesChanged: 0,
112
- propsRenamed: 0,
113
- importsRewritten: 0,
114
- warnings: 0
115
- };
116
- let parsed;
117
- try {
118
- parsed = parseArgs({
119
- args: [...argv],
120
- options: {
121
- reverse: { type: 'boolean' },
122
- 'dry-run': { type: 'boolean' },
123
- help: { type: 'boolean' }
124
- },
125
- allowPositionals: true,
126
- strict: true
127
- });
128
- } catch (error) {
129
- log(error instanceof Error ? error.message : String(error));
130
- log(USAGE);
131
- return failure;
132
- }
133
- if (parsed.values.help === true) {
134
- log(USAGE);
135
- return { ...failure, exitCode: 0 };
136
- }
137
- if (parsed.positionals.length === 0) {
138
- log(USAGE);
139
- return failure;
140
- }
141
- for (const path of parsed.positionals) {
142
- if (!existsSync(path)) {
143
- log(`path does not exist: ${path}`);
144
- return failure;
145
- }
146
- }
147
- const direction: Direction = parsed.values.reverse === true ? 'to-poly' : 'to-sui';
148
- const dryRun = parsed.values['dry-run'] === true;
149
-
150
- const files = new Set<string>();
151
- for (const path of parsed.positionals) {
152
- collectFiles(resolve(path), files);
153
- }
154
-
155
- let filesChanged = 0;
156
- let propsRenamed = 0;
157
- let importsRewritten = 0;
158
- let warnings = 0;
159
- for (const file of files) {
160
- const source = readFileSync(file, 'utf8');
161
- const result: TransformResult = file.endsWith('.svelte')
162
- ? transformSvelte(source, file, direction)
163
- : transformModuleSpecifiers(source, file, direction);
164
- // Reported in both directions and in dry runs: it is a 4.0.0 breaking change
165
- // to report, not a rename to apply, so it never contributes to filesChanged.
166
- const childrenWarnings = direction === 'to-sui' ? findChildrenAssignments(source, file) : [];
167
- for (const warning of [...result.warnings, ...childrenWarnings]) {
168
- log(`${warning.file}:${warning.line}:${warning.column} WARN ${warning.message}`);
169
- }
170
- warnings += result.warnings.length + childrenWarnings.length;
171
- if (!result.changed) {
172
- continue;
173
- }
174
- filesChanged += 1;
175
- propsRenamed += result.propsRenamed;
176
- importsRewritten += result.importsRewritten;
177
- if (dryRun) {
178
- printLineDiff(file, source, result.code, log);
179
- } else {
180
- writeFileSync(file, result.code);
181
- log(
182
- `${file}: ${result.propsRenamed} prop(s) renamed, ${result.importsRewritten} import(s) rewritten`
183
- );
184
- }
185
- }
186
- log(
187
- `${dryRun ? '[dry run] ' : ''}scanned ${files.size} file(s), changed ${filesChanged}, ` +
188
- `renamed ${propsRenamed} prop(s), rewrote ${importsRewritten} import(s), ${warnings} warning(s)`
189
- );
190
- return {
191
- exitCode: 0,
192
- filesScanned: files.size,
193
- filesChanged,
194
- propsRenamed,
195
- importsRewritten,
196
- warnings
197
- };
198
- }
199
-
200
- const entryPoint = process.argv.at(1) ?? '';
201
- if (entryPoint !== '' && import.meta.url === pathToFileURL(entryPoint).href) {
202
- const summary = runCodemod(process.argv.slice(2), (line) => {
203
- console.log(line);
204
- });
205
- process.exitCode = summary.exitCode;
206
- }
@@ -1,118 +0,0 @@
1
- /**
2
- * Casing-only prop pairs between this library (SUI) and its fork
3
- * `polymorph-ui-components` (poly). Poly renamed synthesized event props to
4
- * all-lowercase; these are the props whose names differ ONLY in case between
5
- * the two libraries.
6
- *
7
- * Derived mechanically (not copied from docs): the `$props()` destructure of
8
- * every component exported by both `src/lib/index.ts` (SUI @ release) and
9
- * `dist/index.js` of polymorph-ui-components@0.7.0 was parsed with
10
- * `svelte/compiler`, and a pair was accepted only when
11
- * `lower(suiName) === lower(polyName)`, the names differ, and neither side
12
- * also declares the other side's spelling (which would make a rewrite
13
- * ambiguous or unnecessary). Cross-checked against each component's
14
- * `properties.ts` / `properties.d.ts`.
15
- *
16
- * That derivation is deprecation-blind, and one pair had to be corrected by
17
- * hand afterwards: where a component keeps a deprecated alias whose lowercase
18
- * spelling matches the fork's, the alias wins the case-insensitive match and
19
- * outranks the canonical prop. Stepper is the only such pair. `map.test.ts`
20
- * now asserts no target is `@deprecated`, so a future alias cannot repeat it.
21
- *
22
- * Deliberately excluded (same event, different word — a semantic rename, not
23
- * a casing pair; these need a human):
24
- * Gallery: poly `onclose` vs SUI `onDismiss`, poly `onchange` vs SUI `onIndexChange`
25
- * MediaUpload: poly `onchange` vs SUI `onFilesChange`, poly `onerror` vs SUI `onRejected`
26
- * Props spelled identically on both sides (e.g. `onkeydown` on ListItem or
27
- * Modal) are intentionally absent: they need no rewrite. `onkeydown` on Input
28
- * IS listed because SUI's Input only accepts `onKeyDown`.
29
- */
30
-
31
- export type PropPair = {
32
- readonly component: string;
33
- readonly sui: string;
34
- readonly poly: string;
35
- /**
36
- * Superseded SUI spellings that still work. Never a rewrite target, but
37
- * recognized as a source when rewriting back to the fork.
38
- */
39
- readonly suiDeprecatedAliases?: readonly string[];
40
- };
41
-
42
- export const SUI_PACKAGE = '@juspay/svelte-ui-components';
43
- export const POLY_PACKAGE = 'polymorph-ui-components';
44
-
45
- export const PROP_PAIRS: ReadonlyArray<PropPair> = [
46
- { component: 'Gallery', sui: 'onDeleteClick', poly: 'ondeleteclick' },
47
- { component: 'Gallery', sui: 'onEditClick', poly: 'oneditclick' },
48
- { component: 'Gallery', sui: 'onImageClick', poly: 'onimageclick' },
49
- { component: 'Gallery', sui: 'onOpen', poly: 'onopen' },
50
- { component: 'Input', sui: 'onBlur', poly: 'onblur' },
51
- { component: 'Input', sui: 'onClick', poly: 'onclick' },
52
- { component: 'Input', sui: 'onFocus', poly: 'onfocus' },
53
- { component: 'Input', sui: 'onFocusout', poly: 'onfocusout' },
54
- { component: 'Input', sui: 'onInput', poly: 'oninput' },
55
- { component: 'Input', sui: 'onKeyDown', poly: 'onkeydown' },
56
- { component: 'Input', sui: 'onPaste', poly: 'onpaste' },
57
- { component: 'Input', sui: 'onStateChange', poly: 'onstatechange' },
58
- { component: 'ListItem', sui: 'oncenterTextClick', poly: 'oncentertextclick' },
59
- { component: 'ListItem', sui: 'onitemClick', poly: 'onitemclick' },
60
- { component: 'ListItem', sui: 'onleftImageClick', poly: 'onleftimageclick' },
61
- { component: 'ListItem', sui: 'onrightImageClick', poly: 'onrightimageclick' },
62
- { component: 'ListItem', sui: 'ontopSectionClick', poly: 'ontopsectionclick' },
63
- { component: 'MediaUpload', sui: 'onRemove', poly: 'onremove' },
64
- { component: 'Modal', sui: 'onheaderLeftImageClick', poly: 'onheaderleftimageclick' },
65
- { component: 'Modal', sui: 'onheaderRightImageClick', poly: 'onheaderrightimageclick' },
66
- { component: 'Modal', sui: 'onoverlayClick', poly: 'onoverlayclick' },
67
- { component: 'Modal', sui: 'onprimaryButtonClick', poly: 'onprimarybuttonclick' },
68
- { component: 'Modal', sui: 'onsecondaryButtonClick', poly: 'onsecondarybuttonclick' },
69
- // The lowercase match here is `onhandleStepClick`, which SUI deprecates in
70
- // favour of `onstepclick`. Rewriting to the alias would be case-correct and
71
- // still wrong: it is the one spelling of this event scheduled for removal.
72
- {
73
- component: 'Stepper',
74
- sui: 'onstepclick',
75
- poly: 'onhandlestepclick',
76
- suiDeprecatedAliases: ['onhandleStepClick']
77
- },
78
- { component: 'Table', sui: 'onRowClick', poly: 'onrowclick' },
79
- { component: 'Table', sui: 'onSort', poly: 'onsort' },
80
- { component: 'Toast', sui: 'onToastHide', poly: 'ontoasthide' },
81
- { component: 'Toolbar', sui: 'onbackClick', poly: 'onbackclick' }
82
- ];
83
-
84
- export type Direction = 'to-sui' | 'to-poly';
85
-
86
- export type DirectionConfig = {
87
- readonly fromPackage: string;
88
- readonly toPackage: string;
89
- /** component name -> (source prop name -> target prop name) */
90
- readonly renames: ReadonlyMap<string, ReadonlyMap<string, string>>;
91
- /** every source prop name across all components, for unresolved-tag warnings */
92
- readonly allFromProps: ReadonlySet<string>;
93
- };
94
-
95
- export function directionConfig(direction: Direction): DirectionConfig {
96
- const renames = new Map<string, Map<string, string>>();
97
- const allFromProps = new Set<string>();
98
- for (const pair of PROP_PAIRS) {
99
- const table = renames.get(pair.component) ?? new Map<string, string>();
100
- // Deprecated aliases are sources, never targets: a consumer moving to SUI
101
- // lands on the canonical prop, while one moving back to the fork is
102
- // recognized whichever spelling they are currently on.
103
- const sources =
104
- direction === 'to-sui' ? [pair.poly] : [pair.sui, ...(pair.suiDeprecatedAliases ?? [])];
105
- const to = direction === 'to-sui' ? pair.sui : pair.poly;
106
- for (const from of sources) {
107
- table.set(from, to);
108
- allFromProps.add(from);
109
- }
110
- renames.set(pair.component, table);
111
- }
112
- return {
113
- fromPackage: direction === 'to-sui' ? POLY_PACKAGE : SUI_PACKAGE,
114
- toPackage: direction === 'to-sui' ? SUI_PACKAGE : POLY_PACKAGE,
115
- renames,
116
- allFromProps
117
- };
118
- }