bestax-migrate 2.2.2 → 2.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 (54) hide show
  1. package/README.md +12 -10
  2. package/dist/sources/_shared/imports.d.ts +28 -0
  3. package/dist/sources/_shared/imports.d.ts.map +1 -1
  4. package/dist/sources/_shared/imports.js +62 -0
  5. package/dist/sources/_shared/jsx-utils.d.ts +17 -0
  6. package/dist/sources/_shared/jsx-utils.d.ts.map +1 -1
  7. package/dist/sources/_shared/jsx-utils.js +49 -1
  8. package/dist/sources/_shared/props.d.ts +17 -0
  9. package/dist/sources/_shared/props.d.ts.map +1 -1
  10. package/dist/sources/_shared/props.js +72 -3
  11. package/dist/sources/_shared/specials-utils.d.ts +49 -3
  12. package/dist/sources/_shared/specials-utils.d.ts.map +1 -1
  13. package/dist/sources/_shared/specials-utils.js +165 -5
  14. package/dist/sources/_shared/viewports.d.ts +17 -0
  15. package/dist/sources/_shared/viewports.d.ts.map +1 -0
  16. package/dist/sources/_shared/viewports.js +32 -0
  17. package/dist/sources/bloomer/deps.d.ts +17 -0
  18. package/dist/sources/bloomer/deps.d.ts.map +1 -0
  19. package/dist/sources/bloomer/deps.js +119 -0
  20. package/dist/sources/bloomer/index.d.ts +3 -0
  21. package/dist/sources/bloomer/index.d.ts.map +1 -0
  22. package/dist/sources/bloomer/index.js +10 -0
  23. package/dist/sources/bloomer/mapping.d.ts +84 -0
  24. package/dist/sources/bloomer/mapping.d.ts.map +1 -0
  25. package/dist/sources/bloomer/mapping.js +988 -0
  26. package/dist/sources/bloomer/responsive.d.ts +39 -0
  27. package/dist/sources/bloomer/responsive.d.ts.map +1 -0
  28. package/dist/sources/bloomer/responsive.js +259 -0
  29. package/dist/sources/bloomer/specials.d.ts +19 -0
  30. package/dist/sources/bloomer/specials.d.ts.map +1 -0
  31. package/dist/sources/bloomer/specials.js +774 -0
  32. package/dist/sources/bloomer/styles.d.ts +13 -0
  33. package/dist/sources/bloomer/styles.d.ts.map +1 -0
  34. package/dist/sources/bloomer/styles.js +17 -0
  35. package/dist/sources/bloomer/transform.d.ts +27 -0
  36. package/dist/sources/bloomer/transform.d.ts.map +1 -0
  37. package/dist/sources/bloomer/transform.js +826 -0
  38. package/dist/sources/rbx/responsive.d.ts.map +1 -1
  39. package/dist/sources/rbx/responsive.js +1 -31
  40. package/dist/sources/rbx/specials.d.ts.map +1 -1
  41. package/dist/sources/rbx/specials.js +14 -91
  42. package/dist/sources/rbx/transform.d.ts.map +1 -1
  43. package/dist/sources/rbx/transform.js +168 -78
  44. package/dist/sources/react-bulma-components/responsive.d.ts.map +1 -1
  45. package/dist/sources/react-bulma-components/responsive.js +2 -14
  46. package/dist/sources/react-bulma-components/specials.d.ts.map +1 -1
  47. package/dist/sources/react-bulma-components/specials.js +33 -17
  48. package/dist/sources/react-bulma-components/transform.d.ts.map +1 -1
  49. package/dist/sources/react-bulma-components/transform.js +168 -78
  50. package/dist/sources/registry.d.ts.map +1 -1
  51. package/dist/sources/registry.js +2 -0
  52. package/dist/types.d.ts +11 -0
  53. package/dist/types.d.ts.map +1 -1
  54. package/package.json +3 -2
package/README.md CHANGED
@@ -13,10 +13,11 @@ Codemods that migrate existing React apps to [`@allxsmith/bestax-bulma`](https:/
13
13
 
14
14
  Currently supported source libraries:
15
15
 
16
- | Source | Status |
17
- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
18
- | [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |
19
- | [`rbx`](https://github.com/dfee/rbx) (v2) | ✅ Full export surface mapped (a few patterns are flagged as TODOs) |
16
+ | Source | Status |
17
+ | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
18
+ | [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |
19
+ | [`rbx`](https://github.com/dfee/rbx) (v2) | ✅ Full export surface mapped (a few patterns are flagged as TODOs) |
20
+ | [`bloomer`](https://github.com/AlgusDark/bloomer) (0.6) | ✅ All 108 exports mapped (Font Awesome 4 icons and Bulma 0.4's `Nav` are flagged) |
20
21
 
21
22
  Pass the source library as the first argument: `bestax-migrate <source> <paths…>`.
22
23
 
@@ -33,8 +34,9 @@ the app being migrated — the source is read as text and is never executed.
33
34
  ```bash
34
35
  # Preview what would change (no writes)
35
36
  pnpm dlx bestax-migrate react-bulma-components src/ --dry
36
- # …or, for an rbx app
37
+ # …or, for an rbx or bloomer app
37
38
  pnpm dlx bestax-migrate rbx src/ --dry
39
+ pnpm dlx bestax-migrate bloomer src/ --dry
38
40
 
39
41
  # Apply the migration
40
42
  pnpm dlx bestax-migrate react-bulma-components src/
@@ -45,14 +47,14 @@ npm and yarn work too: `npx bestax-migrate …` / `yarn dlx bestax-migrate …`.
45
47
  The codemod uses [jscodeshift](https://github.com/facebook/jscodeshift) to:
46
48
 
47
49
  - rewrite the source library's imports to `@allxsmith/bestax-bulma` (including destructuring and namespace imports)
48
- - rename components and compound sub-components (`Form.Textarea` → `TextArea`, `Card.Footer.Item` → `Card.FooterItem`, `Hero.Footer` → `Hero.Foot`, …)
50
+ - rename components and compound sub-components (`Form.Textarea` → `TextArea`, `Card.Footer.Item` → `Card.FooterItem`, `Hero.Footer` → `Hero.Foot`, …) — and, for bloomer, its flat names onto bestax's compounds (`CardHeaderTitle` → `Card.Header.Title`)
49
51
  - convert props (`renderAs` → `as`, `loading` → `isLoading`, numeric spacing/text sizes → string unions, `textAlign="center"` → `textAlign="centered"`, …)
50
- - flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`)
52
+ - flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`) and bloomer's `isDisplay`/`isHidden` strings, arrays and objects (`isHidden="touch"` → `visibilityTouch="hidden"`)
51
53
  - restructure patterns bestax models differently (`Table.Container`, Navbar dropdowns, `Form.Help`, icon-font children → `<Icon name=…>`)
52
54
  - migrate stylesheets: CSS imports converge on `@allxsmith/bestax-bulma/bestax.css`, and SCSS files move from Bulma 0.9's `@import` + `$var !default` overrides to `@use 'bulma/sass' with (…)` plus `@use '@allxsmith/bestax-bulma/scss/extras'`
53
- - update `package.json`: remove the source library, add `@allxsmith/bestax-bulma`, raise a declared pre-1.0 `bulma` to `^1` (adding it only when your sources import `bulma/…` directly — otherwise it arrives transitively), and swap the dead `node-sass` for dart `sass` (no install is ever run). Migrating **rbx** is what frees an app from Bulma 0.7.5: rbx pinned it as a _direct_ dependency, so the app could not choose its own Bulma version at all. The four Bulma extensions rbx also pulled in (`bulma-badge`, `bulma-divider`, `bulma-pageloader`, `bulma-tooltip`) are **reported rather than removed** — bestax replaces all four, but a manifest entry is a deliberate declaration and your own Sass may import them
55
+ - update `package.json`: remove the source library, add `@allxsmith/bestax-bulma`, raise a declared pre-1.0 `bulma` to `^1` (adding it only when your sources import `bulma/…` directly — otherwise it arrives transitively), and swap the dead `node-sass` for dart `sass` (no install is ever run). Migrating **rbx** is what frees an app from Bulma 0.7.5: rbx pinned it as a _direct_ dependency, so the app could not choose its own Bulma version at all. The four Bulma extensions rbx also pulled in (`bulma-badge`, `bulma-divider`, `bulma-pageloader`, `bulma-tooltip`) are **reported rather than removed** — bestax replaces all four, but a manifest entry is a deliberate declaration and your own Sass may import them. A **bloomer** app declared its own Bulma 0.6, which is what gets bumped
54
56
 
55
- Anything without a safe automatic conversion is left in place with a `// TODO(bestax-migrate): …` comment, and the run ends with a report of every TODO by file and line. TODOs are expected output, not errors — resolve them with the migration guide ([react-bulma-components](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components), [rbx](https://bestax.io/docs/guides/getting-started/migration/rbx)), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:
57
+ Anything without a safe automatic conversion is left in place with a `// TODO(bestax-migrate): …` comment, and the run ends with a report of every TODO by file and line. TODOs are expected output, not errors — resolve them with the migration guide ([react-bulma-components](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components), [rbx](https://bestax.io/docs/guides/getting-started/migration/rbx), [bloomer](https://bestax.io/docs/guides/getting-started/migration/bloomer)), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:
56
58
 
57
59
  ```bash
58
60
  npx skills add https://github.com/allxsmith/bestax --skill bestax-migrate
@@ -74,7 +76,7 @@ npx skills add https://github.com/allxsmith/bestax --skill bestax-migrate
74
76
  2. Search for `TODO(bestax-migrate)` and resolve each comment
75
77
  3. Typecheck/build and review the rendered app
76
78
 
77
- Full walkthrough: [react-bulma-components migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components) · [rbx migration guide](https://bestax.io/docs/guides/getting-started/migration/rbx).
79
+ Full walkthrough: [react-bulma-components migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components) · [rbx migration guide](https://bestax.io/docs/guides/getting-started/migration/rbx) · [bloomer migration guide](https://bestax.io/docs/guides/getting-started/migration/bloomer).
78
80
 
79
81
  ## Hardened by default
80
82
 
@@ -43,4 +43,32 @@ export declare function prefersTabs(source: string): boolean;
43
43
  * declarators at any depth.
44
44
  */
45
45
  export declare function resolvesToBinding(path: ASTPath<any>, name: string, expected: unknown): boolean;
46
+ /**
47
+ * Registry of `const { Item } = Card`-style aliases, keyed by the AST node
48
+ * that owns the declaring scope rather than by bare name. Two functions can
49
+ * each destructure `Header` from a different component; a name-keyed map let
50
+ * the second overwrite the first, and both declarations were then pruned
51
+ * while both `<Header…>` references were left resolving to nothing.
52
+ *
53
+ * Resolution walks the reference's ANCESTORS rather than consulting
54
+ * `scope.lookup`, because by the time references are rewritten the alias
55
+ * pass has already pruned the declaration -- so the binding is gone from the
56
+ * scope table, and `path.scope` objects are not identity-stable across
57
+ * traversals either.
58
+ *
59
+ * Source-agnostic: every transform resolves aliases the same way, and #613
60
+ * shipped this block duplicated in two of them.
61
+ */
62
+ export interface AliasRegistry {
63
+ /** Record that `local` in the scope owned by `owner` names `target`. */
64
+ register(owner: unknown, local: string, target: string[]): void;
65
+ /**
66
+ * The canonical path `name` aliases at `at` (a reference's path), or
67
+ * undefined when no alias applies to that reference.
68
+ */
69
+ aliasAt(name: string, at?: unknown): string[] | undefined;
70
+ /** Whether ANY scope aliases `name` — regardless of the reference. */
71
+ anyAlias(name: string): boolean;
72
+ }
73
+ export declare function makeAliasRegistry(): AliasRegistry;
46
74
  //# sourceMappingURL=imports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/imports.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,eAAO,MAAM,MAAM,GAAI,MAAM,GAAG,KAAG,MACyB,CAAC;AAE7D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,WAAW,EACd,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EACrB,gBAAgB,EAAE,MAAM,GACvB,GAAG,CAAC,MAAM,CAAC,CAmEb;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GACjB,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAiBlC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAChB,OAAO,CAST"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/imports.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,eAAO,MAAM,MAAM,GAAI,MAAM,GAAG,KAAG,MACyB,CAAC;AAE7D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,WAAW,EACd,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EACrB,gBAAgB,EAAE,MAAM,GACvB,GAAG,CAAC,MAAM,CAAC,CAmEb;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GACjB,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAiBlC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAChB,OAAO,CAST;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAChE;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAC1D,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,wBAAgB,iBAAiB,IAAI,aAAa,CAoEjD"}
@@ -150,3 +150,65 @@ export function resolvesToBinding(path, name, expected) {
150
150
  // the shadowing case it guards against.
151
151
  return !declaring || declaring === expected;
152
152
  }
153
+ export function makeAliasRegistry() {
154
+ const aliasesByOwner = new Map();
155
+ const ownersFor = (name) => {
156
+ const owners = [];
157
+ for (const [owner, perScope] of aliasesByOwner) {
158
+ if (perScope.has(name))
159
+ owners.push(owner);
160
+ }
161
+ return owners;
162
+ };
163
+ const register = (owner, local, target) => {
164
+ let perScope = aliasesByOwner.get(owner);
165
+ if (!perScope) {
166
+ perScope = new Map();
167
+ aliasesByOwner.set(owner, perScope);
168
+ }
169
+ perScope.set(local, target);
170
+ };
171
+ const aliasAt = (name, at) => {
172
+ const owners = ownersFor(name);
173
+ if (owners.length === 0)
174
+ return undefined;
175
+ // Without a reference location there is nothing to walk, so the only
176
+ // owner is the best answer available. WITH one, always walk: an unrelated
177
+ // `Header` parameter in another function must not resolve to the alias
178
+ // merely because the alias is the only one by that name. A single-owner
179
+ // shortcut here rewrote such a parameter to `{ Header: Card.Header }`,
180
+ // which is not even valid syntax.
181
+ if (at === undefined) {
182
+ return owners.length === 1
183
+ ? aliasesByOwner.get(owners[0]).get(name)
184
+ : undefined;
185
+ }
186
+ let cursor = at;
187
+ while (cursor) {
188
+ if (cursor.node !== undefined) {
189
+ const hit = aliasesByOwner.get(cursor.node)?.get(name);
190
+ if (hit) {
191
+ // The walk finds the nearest OWNER, but a binding can intervene
192
+ // between the reference and that owner: `function F(Header)` under
193
+ // a module-level `const { Header } = Card` shadows the alias, and
194
+ // resolving through it rewrote the parameter itself to
195
+ // `F(Card.Header)`. If the scope table still binds the name
196
+ // somewhere other than the owner, that nearer binding wins. (After
197
+ // the alias declaration is pruned the lookup returns nothing for
198
+ // the alias itself, which is the case this must keep allowing.)
199
+ const declaring = at.scope?.lookup(name)?.path?.node;
200
+ if (declaring !== undefined &&
201
+ declaring !== null &&
202
+ declaring !== cursor.node) {
203
+ return undefined;
204
+ }
205
+ return hit;
206
+ }
207
+ }
208
+ cursor = cursor.parent;
209
+ }
210
+ return undefined;
211
+ };
212
+ const anyAlias = (name) => ownersFor(name).length > 0;
213
+ return { register, aliasAt, anyAlias };
214
+ }
@@ -62,6 +62,23 @@ export type LiteralValue = {
62
62
  };
63
63
  /** Extract the literal value of a JSX attribute, if it has one. */
64
64
  export declare function literalValueOf(attr: any): LiteralValue;
65
+ /**
66
+ * The literal value of an expression node (as opposed to `literalValueOf`,
67
+ * which reads a JSX attribute): a string, number or boolean literal's value,
68
+ * otherwise undefined.
69
+ */
70
+ export declare function literalOf(node: any): string | number | boolean | undefined;
71
+ /**
72
+ * Reuse a value node as a JSX attribute value: a string literal can sit bare
73
+ * (`size="one-third"`), anything else needs an expression container.
74
+ */
75
+ export declare function attrValue(j: JSCodeshift, node: any): any;
76
+ /** The static key of an object property (`{ tablet: … }`, `{ 'inline-block': … }`). */
77
+ export declare function propKey(prop: any): string | undefined;
78
+ /** The ObjectExpression inside a JSX attribute value, or null. */
79
+ export declare function objectExpressionOf(value: any): any | null;
80
+ /** The ArrayExpression inside a JSX attribute value, or null. */
81
+ export declare function arrayExpressionOf(value: any): any | null;
65
82
  export type Booleanish = 'truthy' | 'falsy' | 'expression';
66
83
  /**
67
84
  * Classify a JSX attribute by the truthiness the source library evaluates it
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-utils.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/jsx-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jsx-utils.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/jsx-utils.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,50 @@ export function literalValueOf(attr) {
74
74
  }
75
75
  return { kind: 'expression' };
76
76
  }
77
+ /**
78
+ * The literal value of an expression node (as opposed to `literalValueOf`,
79
+ * which reads a JSX attribute): a string, number or boolean literal's value,
80
+ * otherwise undefined.
81
+ */
82
+ export function literalOf(node) {
83
+ if (!node)
84
+ return undefined;
85
+ if (node.type === 'StringLiteral')
86
+ return node.value;
87
+ if (node.type === 'NumericLiteral')
88
+ return node.value;
89
+ if (node.type === 'BooleanLiteral')
90
+ return node.value;
91
+ return undefined;
92
+ }
93
+ /**
94
+ * Reuse a value node as a JSX attribute value: a string literal can sit bare
95
+ * (`size="one-third"`), anything else needs an expression container.
96
+ */
97
+ export function attrValue(j, node) {
98
+ return node?.type === 'StringLiteral'
99
+ ? j.stringLiteral(node.value)
100
+ : j.jsxExpressionContainer(node);
101
+ }
102
+ /** The static key of an object property (`{ tablet: … }`, `{ 'inline-block': … }`). */
103
+ export function propKey(prop) {
104
+ const key = prop.key?.name ?? prop.key?.value;
105
+ return typeof key === 'string' ? key : undefined;
106
+ }
107
+ /** The ObjectExpression inside a JSX attribute value, or null. */
108
+ export function objectExpressionOf(value) {
109
+ return value?.type === 'JSXExpressionContainer' &&
110
+ value.expression?.type === 'ObjectExpression'
111
+ ? value.expression
112
+ : null;
113
+ }
114
+ /** The ArrayExpression inside a JSX attribute value, or null. */
115
+ export function arrayExpressionOf(value) {
116
+ return value?.type === 'JSXExpressionContainer' &&
117
+ value.expression?.type === 'ArrayExpression'
118
+ ? value.expression
119
+ : null;
120
+ }
77
121
  /**
78
122
  * Classify a JSX attribute by the truthiness the source library evaluates it
79
123
  * with at runtime (`!!value`): every statically-known literal (boolean,
@@ -140,7 +184,11 @@ export function addTodo(ctx, path, rule, message) {
140
184
  export function plainElement(j, tag, className, attrs, children, selfClosing = false) {
141
185
  const allAttrs = [...attrs];
142
186
  if (className) {
143
- allAttrs.unshift(makeAttr(j, 'className', className));
187
+ // After the LAST spread, so a `className` inside one cannot replace the
188
+ // class this element exists for, while every other attribute keeps the
189
+ // place (and so the precedence) it had in the source.
190
+ const lastSpread = allAttrs.reduce((last, a, i) => a.type === 'JSXSpreadAttribute' ? i : last, -1);
191
+ allAttrs.splice(lastSpread + 1, 0, makeAttr(j, 'className', className));
144
192
  }
145
193
  const opening = j.jsxOpeningElement(j.jsxIdentifier(tag), allAttrs, selfClosing);
146
194
  const closing = selfClosing
@@ -9,6 +9,23 @@
9
9
  import type { ASTPath } from 'jscodeshift';
10
10
  import type { PropAction } from '../../types.js';
11
11
  import { type TransformContext } from './jsx-utils.js';
12
+ /**
13
+ * Add a converted attribute unless the target name is already present — two
14
+ * source props can map onto one bestax prop (e.g. RBC's `textTransform` +
15
+ * `italic`), and a silent duplicate would be invalid JSX.
16
+ */
17
+ export declare function addConverted(ctx: TransformContext, path: ASTPath<any>, element: any, originalName: string, name: string, value: string | undefined): void;
18
+ /**
19
+ * The same refusal for an attribute the caller has already built — a numeric
20
+ * `size={6}` or a reused expression node, which `makeAttr` cannot express.
21
+ */
22
+ export declare function addAttrOnce(ctx: TransformContext, path: ASTPath<any>, element: any, originalName: string, attr: any): void;
23
+ /**
24
+ * Merge a Bulma class into the element's `className`: appended to a string
25
+ * literal, written fresh when there is none, and a TODO when the existing
26
+ * value is dynamic (the class cannot be spliced into an expression safely).
27
+ */
28
+ export declare function mergeClass(ctx: TransformContext, path: ASTPath<any>, element: any, cls: string, originalName: string): void;
12
29
  /** Apply one PropAction to `attr` on `element`. */
13
30
  export declare function applyPropAction(ctx: TransformContext, path: ASTPath<any>, element: any, attr: any, action: PropAction): void;
14
31
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/props.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EASL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AA6BxB,mDAAmD;AACnD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,UAAU,GACjB,IAAI,CA6HN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACzC,IAAI,CAQN"}
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/props.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EASL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAIxB;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,GAAG,GACR,IAAI,CAmBN;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,IAAI,CAoBN;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,UAAU,GACjB,IAAI,CAqLN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACzC,IAAI,CAQN"}
@@ -13,12 +13,48 @@ import { addAttr, addTodo, attributesOf, findAttr, literalValueOf, makeAttr, rem
13
13
  * source props can map onto one bestax prop (e.g. RBC's `textTransform` +
14
14
  * `italic`), and a silent duplicate would be invalid JSX.
15
15
  */
16
- function addConverted(ctx, path, element, originalName, name, value) {
16
+ export function addConverted(ctx, path, element, originalName, name, value) {
17
+ addAttrOnce(ctx, path, element, originalName, makeAttr(ctx.j, name, value));
18
+ }
19
+ /**
20
+ * The same refusal for an attribute the caller has already built — a numeric
21
+ * `size={6}` or a reused expression node, which `makeAttr` cannot express.
22
+ */
23
+ export function addAttrOnce(ctx, path, element, originalName, attr) {
24
+ const name = attr.name.name;
17
25
  if (findAttr(element, name)) {
18
- addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` maps to \`${name}${value === undefined ? '' : `="${value}"`}\`, but \`${name}\` is already set on this element; reconcile by hand`);
26
+ const value = attr.value;
27
+ const rendered = value == null
28
+ ? ''
29
+ : value.type === 'StringLiteral'
30
+ ? `="${value.value}"`
31
+ : '={…}';
32
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` maps to \`${name}${rendered}\`, but \`${name}\` is already set on this element; reconcile by hand`);
19
33
  return;
20
34
  }
21
- addAttr(element, makeAttr(ctx.j, name, value));
35
+ addAttr(element, attr);
36
+ }
37
+ /**
38
+ * Merge a Bulma class into the element's `className`: appended to a string
39
+ * literal, written fresh when there is none, and a TODO when the existing
40
+ * value is dynamic (the class cannot be spliced into an expression safely).
41
+ */
42
+ export function mergeClass(ctx, path, element, cls, originalName) {
43
+ const { j } = ctx;
44
+ const existing = findAttr(element, 'className');
45
+ if (!existing) {
46
+ addAttr(element, makeAttr(j, 'className', cls));
47
+ return;
48
+ }
49
+ const literal = literalValueOf(existing);
50
+ if (literal.kind === 'string') {
51
+ const classes = literal.value.split(/\s+/).filter(Boolean);
52
+ if (!classes.includes(cls))
53
+ classes.push(cls);
54
+ existing.value = j.stringLiteral(classes.join(' '));
55
+ return;
56
+ }
57
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` becomes the \`${cls}\` class, but \`className\` is dynamic here; add \`${cls}\` to it by hand`);
22
58
  }
23
59
  /** Apply one PropAction to `attr` on `element`. */
24
60
  export function applyPropAction(ctx, path, element, attr, action) {
@@ -29,6 +65,30 @@ export function applyPropAction(ctx, path, element, attr, action) {
29
65
  ctx.dirty = true;
30
66
  return;
31
67
  }
68
+ if (action.toClass) {
69
+ const resolved = resolveBooleanish(attr);
70
+ if (resolved === 'expression') {
71
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` has a dynamic value; bestax has no prop for it — add the \`${action.toClass}\` class conditionally by hand`);
72
+ return;
73
+ }
74
+ removeAttr(element, attr);
75
+ ctx.dirty = true;
76
+ if (resolved === 'truthy') {
77
+ mergeClass(ctx, path, element, action.toClass, originalName);
78
+ }
79
+ return;
80
+ }
81
+ if (action.toClassPrefix) {
82
+ const value = literalValueOf(attr);
83
+ if (value.kind !== 'string') {
84
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` has a dynamic value; bestax has no prop for it — add the \`${action.toClassPrefix}<value>\` class by hand`);
85
+ return;
86
+ }
87
+ removeAttr(element, attr);
88
+ ctx.dirty = true;
89
+ mergeClass(ctx, path, element, `${action.toClassPrefix}${value.value}`, originalName);
90
+ return;
91
+ }
32
92
  if (action.todo) {
33
93
  addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` — ${action.todo}`);
34
94
  return;
@@ -80,6 +140,15 @@ export function applyPropAction(ctx, path, element, attr, action) {
80
140
  return;
81
141
  }
82
142
  let renamedTo = originalName;
143
+ if (action.rename &&
144
+ action.rename !== originalName &&
145
+ findAttr(element, action.rename)) {
146
+ // Two source props can converge on one bestax prop (`isSize` and
147
+ // `isFullHeight` both on `size`); renaming over the one already written
148
+ // produced a duplicate attribute, which is invalid JSX.
149
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` maps to \`${action.rename}\`, but \`${action.rename}\` is already set on this element; reconcile by hand`);
150
+ return;
151
+ }
83
152
  if (action.rename) {
84
153
  attr.name = j.jsxIdentifier(action.rename);
85
154
  renamedTo = action.rename;
@@ -36,10 +36,56 @@ export declare function makeStripModifierProps(universalProps: Record<string, Pr
36
36
  * can't be merged safely — keep the base class and leave a TODO.
37
37
  */
38
38
  export declare function mergeClassName(ctx: TransformContext, path: ASTPath<any>, element: any, base: string | undefined, where: string): string | undefined;
39
- /** Parse an icon-font <i className="..."> into bestax Icon name/library/variant. */
40
- export declare function parseIconClasses(className: string): {
39
+ /** What an icon-font class string says about a bestax `Icon`. */
40
+ export interface ParsedIconClasses {
41
41
  name: string;
42
42
  library?: string;
43
43
  variant?: string;
44
- } | null;
44
+ /** Recognised modifier classes (`fa-spin`, `fa-2x`, `mdi-48px`) — bestax's `features`. */
45
+ features: string[];
46
+ /**
47
+ * Tokens that are neither the icon, its style, nor a modifier the library
48
+ * documents — an app's own class. bestax's Icon has nowhere to put them
49
+ * on the glyph, so a caller that wants exact markup keeps the child.
50
+ */
51
+ leftovers: string[];
52
+ }
53
+ /**
54
+ * Parse an icon-font class string (`fas fa-home fa-spin`, `mdi mdi-account`)
55
+ * into bestax Icon props. Returns null when no icon name can be read.
56
+ */
57
+ export declare function parseIconClasses(className: string): ParsedIconClasses | null;
58
+ /**
59
+ * Write a parsed icon onto a bestax `Icon`-shaped element: `name`, then
60
+ * `library`/`variant` when known, then `features` — one string, or an array
61
+ * literal when there are several — and make the element self-closing.
62
+ */
63
+ export declare function applyIconProps(ctx: TransformContext, path: ASTPath<any>, element: any, parsed: ParsedIconClasses): void;
64
+ /**
65
+ * Turn a literal modifier prop into an `is-*` class fragment for an element
66
+ * on its way to becoming plain HTML. Returns the class (or undefined) and
67
+ * always removes the attribute.
68
+ */
69
+ export declare function modifierClass(ctx: TransformContext, path: ASTPath<any>, element: any, prop: string, base: string, where: string): string;
70
+ /**
71
+ * A source that puts `as` (or its own name for it) on every component can
72
+ * land, through a handler that picks its target from a prop value, on a
73
+ * bestax component that has no `as` — Media.Item resolves to
74
+ * Left/Content/Right where only Left declares one. Opting into `as` in the
75
+ * mapping table cannot express that, so the target has to be checked after
76
+ * it is picked.
77
+ */
78
+ export declare function restrictAsToTargets(ctx: TransformContext, path: ASTPath<any>, element: any, target: string | undefined, allowed: string[], prop?: string): void;
79
+ /** Attribute filter a source applies before an element becomes plain HTML. */
80
+ export type AttrStrip = (ctx: TransformContext, path: ASTPath<any>, attrs: any[], where: string) => any[];
81
+ /**
82
+ * The two structural rewrites every source needs, bound to that source's own
83
+ * attribute strip (its modifier vocabulary is the one thing that differs):
84
+ * replacing an element with plain HTML, and folding a wrapper onto the single
85
+ * child it exists to wrap.
86
+ */
87
+ export declare function makeStructuralHelpers(strip: AttrStrip): {
88
+ replaceWithPlain: (ctx: TransformContext, path: ASTPath<any>, element: any, tag: string, className: string | undefined, where: string) => SpecialResult;
89
+ collapseOntoChild: (ctx: TransformContext, path: ASTPath<any>, element: any, where: string, expected: string | string[]) => SpecialResult | null;
90
+ };
45
91
  //# sourceMappingURL=specials-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"specials-utils.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/specials-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,KACT,aAAa,CAAC;AAEnB,4EAA4E;AAC5E,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,QAAQ,EAAE,MAAM,GACf,aAAa,CAuBf;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC1C,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,IAGlD,KAAK,gBAAgB,EACrB,MAAM,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,GAAG,EAAE,EACZ,OAAO,MAAM,KACZ,GAAG,EAAE,CAuBT;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAiBpB;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA2C7D"}
1
+ {"version":3,"file":"specials-utils.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/specials-utils.ts"],"names":[],"mappings":"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"}