bestax-migrate 0.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 (47) hide show
  1. package/README.md +59 -0
  2. package/dist/cli.d.ts +22 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +225 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +12 -0
  8. package/dist/report.d.ts +24 -0
  9. package/dist/report.d.ts.map +1 -0
  10. package/dist/report.js +66 -0
  11. package/dist/runner.d.ts +16 -0
  12. package/dist/runner.d.ts.map +1 -0
  13. package/dist/runner.js +69 -0
  14. package/dist/sources/react-bulma-components/deps.d.ts +9 -0
  15. package/dist/sources/react-bulma-components/deps.d.ts.map +1 -0
  16. package/dist/sources/react-bulma-components/deps.js +96 -0
  17. package/dist/sources/react-bulma-components/index.d.ts +3 -0
  18. package/dist/sources/react-bulma-components/index.d.ts.map +1 -0
  19. package/dist/sources/react-bulma-components/index.js +10 -0
  20. package/dist/sources/react-bulma-components/jsx-utils.d.ts +69 -0
  21. package/dist/sources/react-bulma-components/jsx-utils.d.ts.map +1 -0
  22. package/dist/sources/react-bulma-components/jsx-utils.js +130 -0
  23. package/dist/sources/react-bulma-components/mapping.d.ts +31 -0
  24. package/dist/sources/react-bulma-components/mapping.d.ts.map +1 -0
  25. package/dist/sources/react-bulma-components/mapping.js +852 -0
  26. package/dist/sources/react-bulma-components/props.d.ts +15 -0
  27. package/dist/sources/react-bulma-components/props.d.ts.map +1 -0
  28. package/dist/sources/react-bulma-components/props.js +124 -0
  29. package/dist/sources/react-bulma-components/responsive.d.ts +17 -0
  30. package/dist/sources/react-bulma-components/responsive.d.ts.map +1 -0
  31. package/dist/sources/react-bulma-components/responsive.js +113 -0
  32. package/dist/sources/react-bulma-components/specials.d.ts +23 -0
  33. package/dist/sources/react-bulma-components/specials.d.ts.map +1 -0
  34. package/dist/sources/react-bulma-components/specials.js +546 -0
  35. package/dist/sources/react-bulma-components/styles.d.ts +13 -0
  36. package/dist/sources/react-bulma-components/styles.d.ts.map +1 -0
  37. package/dist/sources/react-bulma-components/styles.js +199 -0
  38. package/dist/sources/react-bulma-components/transform.d.ts +19 -0
  39. package/dist/sources/react-bulma-components/transform.d.ts.map +1 -0
  40. package/dist/sources/react-bulma-components/transform.js +495 -0
  41. package/dist/sources/registry.d.ts +9 -0
  42. package/dist/sources/registry.d.ts.map +1 -0
  43. package/dist/sources/registry.js +14 -0
  44. package/dist/types.d.ts +122 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +9 -0
  47. package/package.json +74 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Prop-level conversion: applies a PropAction to a single attribute, plus the
3
+ * universal modifier-prop pass shared by every mapped component.
4
+ */
5
+ import type { ASTPath } from 'jscodeshift';
6
+ import type { PropAction } from '../../types.js';
7
+ import { type TransformContext } from './jsx-utils.js';
8
+ /** Apply one PropAction to `attr` on `element`. */
9
+ export declare function applyPropAction(ctx: TransformContext, path: ASTPath<any>, element: any, attr: any, action: PropAction): void;
10
+ /**
11
+ * Apply the universal RBC modifier-prop conversions to every attribute that
12
+ * was not already handled by the component's own prop map.
13
+ */
14
+ export declare function applyUniversalProps(ctx: TransformContext, path: ASTPath<any>, element: any, handled: Set<string>): void;
15
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/props.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAQL,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,CA4HN;AAED;;;GAGG;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,GACnB,IAAI,CAQN"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Prop-level conversion: applies a PropAction to a single attribute, plus the
3
+ * universal modifier-prop pass shared by every mapped component.
4
+ */
5
+ import { UNIVERSAL_PROPS } from './mapping.js';
6
+ import { addAttr, addTodo, attributesOf, findAttr, literalValueOf, makeAttr, removeAttr, } from './jsx-utils.js';
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ /**
9
+ * Add a converted attribute unless the target name is already present — two
10
+ * RBC props can map onto one bestax prop (e.g. `textTransform` + `italic`),
11
+ * and a silent duplicate would be invalid JSX.
12
+ */
13
+ function addConverted(ctx, path, element, originalName, name, value) {
14
+ if (findAttr(element, name)) {
15
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` maps to \`${name}${value === undefined ? '' : `="${value}"`}\`, but \`${name}\` is already set on this element; reconcile by hand`);
16
+ return;
17
+ }
18
+ addAttr(element, makeAttr(ctx.j, name, value));
19
+ }
20
+ /** Apply one PropAction to `attr` on `element`. */
21
+ export function applyPropAction(ctx, path, element, attr, action) {
22
+ const { j } = ctx;
23
+ const originalName = attr.name.name;
24
+ if (action.drop) {
25
+ removeAttr(element, attr);
26
+ ctx.dirty = true;
27
+ return;
28
+ }
29
+ if (action.todo) {
30
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` — ${action.todo}`);
31
+ return;
32
+ }
33
+ const literal = literalValueOf(attr);
34
+ if (action.valueTodo &&
35
+ literal.kind === 'string' &&
36
+ action.valueTodo[literal.value]) {
37
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}="${literal.value}"\` — ${action.valueTodo[literal.value]}`);
38
+ return;
39
+ }
40
+ if (action.valueToProp) {
41
+ if (literal.kind === 'string') {
42
+ const mapped = action.valueMap?.[literal.value];
43
+ if (mapped) {
44
+ removeAttr(element, attr);
45
+ for (const name of mapped.split(' ')) {
46
+ addConverted(ctx, path, element, originalName, name, undefined);
47
+ }
48
+ ctx.dirty = true;
49
+ }
50
+ // Unmapped literal values are intentionally left untouched.
51
+ }
52
+ else {
53
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` has a dynamic value; map it to the matching bestax boolean prop by hand`);
54
+ }
55
+ return;
56
+ }
57
+ if (action.booleanToProp) {
58
+ const { name, value } = action.booleanToProp;
59
+ if (literal.kind === 'boolean' && literal.value === true) {
60
+ removeAttr(element, attr);
61
+ addConverted(ctx, path, element, originalName, name, value);
62
+ ctx.dirty = true;
63
+ }
64
+ else if (literal.kind === 'boolean' && literal.value === false) {
65
+ removeAttr(element, attr);
66
+ ctx.dirty = true;
67
+ }
68
+ else if (value === undefined) {
69
+ // Pure boolean rename — a dynamic expression can carry over.
70
+ attr.name = j.jsxIdentifier(name);
71
+ ctx.dirty = true;
72
+ }
73
+ else {
74
+ addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}\` has a dynamic value; set \`${name}="${value}"\` conditionally by hand`);
75
+ }
76
+ return;
77
+ }
78
+ let renamedTo = originalName;
79
+ if (action.rename) {
80
+ attr.name = j.jsxIdentifier(action.rename);
81
+ renamedTo = action.rename;
82
+ ctx.dirty = true;
83
+ }
84
+ if (action.numberToString) {
85
+ if (literal.kind === 'number') {
86
+ attr.value = j.stringLiteral(String(literal.value));
87
+ ctx.dirty = true;
88
+ }
89
+ else if (literal.kind === 'expression') {
90
+ addTodo(ctx, path, `prop:${originalName}`, `\`${renamedTo}\` takes a string in bestax-bulma ('${originalName}={4}' → '${renamedTo}="4"'); convert the dynamic value`);
91
+ }
92
+ return;
93
+ }
94
+ if (action.valueMap) {
95
+ if (literal.kind === 'string') {
96
+ const mapped = action.valueMap[literal.value];
97
+ if (mapped && mapped !== literal.value) {
98
+ attr.value = j.stringLiteral(mapped);
99
+ ctx.dirty = true;
100
+ }
101
+ }
102
+ else if (literal.kind === 'expression') {
103
+ addTodo(ctx, path, `prop:${originalName}`, `\`${renamedTo}\` values differ in bestax-bulma (${Object.entries(action.valueMap)
104
+ .filter(([from, to]) => from !== to)
105
+ .map(([from, to]) => `'${from}'→'${to}'`)
106
+ .join(', ')}); convert the dynamic value`);
107
+ }
108
+ }
109
+ }
110
+ /**
111
+ * Apply the universal RBC modifier-prop conversions to every attribute that
112
+ * was not already handled by the component's own prop map.
113
+ */
114
+ export function applyUniversalProps(ctx, path, element, handled) {
115
+ for (const attr of [...attributesOf(element)]) {
116
+ const name = attr.name.name;
117
+ if (handled.has(name))
118
+ continue;
119
+ const action = UNIVERSAL_PROPS[name];
120
+ if (!action)
121
+ continue;
122
+ applyPropAction(ctx, path, element, attr, action);
123
+ }
124
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Flattens RBC's responsive breakpoint-object props into bestax-bulma's flat
3
+ * per-viewport props:
4
+ *
5
+ * <Element mobile={{ display: 'flex', textSize: 4 }} />
6
+ * → displayMobile="flex" textSizeMobile="4"
7
+ * <Columns.Column tablet={{ size: 6, narrow: true }} />
8
+ * → sizeTablet={6} isNarrowTablet
9
+ *
10
+ * touch / untilWidescreen / untilFullhd have no bestax equivalents and get a
11
+ * TODO. Non-object or dynamic values get a TODO.
12
+ */
13
+ import type { ASTPath } from 'jscodeshift';
14
+ import { type TransformContext } from './jsx-utils.js';
15
+ export type ResponsiveKind = 'generic' | 'columns' | 'column';
16
+ export declare function flattenResponsiveProps(ctx: TransformContext, path: ASTPath<any>, element: any, kind: ResponsiveKind): void;
17
+ //# sourceMappingURL=responsive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/responsive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAkB9D,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,cAAc,GACnB,IAAI,CAkHN"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Flattens RBC's responsive breakpoint-object props into bestax-bulma's flat
3
+ * per-viewport props:
4
+ *
5
+ * <Element mobile={{ display: 'flex', textSize: 4 }} />
6
+ * → displayMobile="flex" textSizeMobile="4"
7
+ * <Columns.Column tablet={{ size: 6, narrow: true }} />
8
+ * → sizeTablet={6} isNarrowTablet
9
+ *
10
+ * touch / untilWidescreen / untilFullhd have no bestax equivalents and get a
11
+ * TODO. Non-object or dynamic values get a TODO.
12
+ */
13
+ import { RESPONSIVE_BREAKPOINTS } from './mapping.js';
14
+ import { addAttr, addTodo, attributesOf, makeAttr, removeAttr, } from './jsx-utils.js';
15
+ const TEXT_ALIGN_MAP = {
16
+ center: 'centered',
17
+ justify: 'justified',
18
+ left: 'left',
19
+ right: 'right',
20
+ };
21
+ function literalOf(prop) {
22
+ const v = prop.value;
23
+ if (!v)
24
+ return undefined;
25
+ if (v.type === 'StringLiteral')
26
+ return v.value;
27
+ if (v.type === 'NumericLiteral')
28
+ return v.value;
29
+ if (v.type === 'BooleanLiteral')
30
+ return v.value;
31
+ return undefined;
32
+ }
33
+ export function flattenResponsiveProps(ctx, path, element, kind) {
34
+ const { j } = ctx;
35
+ for (const attr of [...attributesOf(element)]) {
36
+ const name = attr.name.name;
37
+ if (!(name in RESPONSIVE_BREAKPOINTS))
38
+ continue;
39
+ const suffix = RESPONSIVE_BREAKPOINTS[name];
40
+ if (suffix === null) {
41
+ addTodo(ctx, path, 'responsive', `no bestax-bulma helper variants for the \`${name}\` breakpoint; restyle with CSS or drop it`);
42
+ continue;
43
+ }
44
+ const value = attr.value;
45
+ const objectExpr = value?.type === 'JSXExpressionContainer' &&
46
+ value.expression?.type === 'ObjectExpression'
47
+ ? value.expression
48
+ : null;
49
+ if (!objectExpr) {
50
+ addTodo(ctx, path, 'responsive', `\`${name}\` must be an inline object literal to flatten to bestax per-viewport props; convert it by hand`);
51
+ continue;
52
+ }
53
+ const remaining = [];
54
+ for (const prop of objectExpr.properties) {
55
+ if (prop.type !== 'ObjectProperty' && prop.type !== 'Property') {
56
+ remaining.push(prop);
57
+ continue;
58
+ }
59
+ const key = prop.key?.name ?? prop.key?.value;
60
+ const literal = literalOf(prop);
61
+ if (key === 'display' && typeof literal === 'string') {
62
+ if (literal === 'hidden') {
63
+ addAttr(element, makeAttr(j, `visibility${suffix}`, 'hidden'));
64
+ }
65
+ else if (literal === 'relative') {
66
+ remaining.push(prop);
67
+ addTodo(ctx, path, 'responsive', `\`${name}.display: 'relative'\` has no bestax per-viewport equivalent`);
68
+ continue;
69
+ }
70
+ else {
71
+ addAttr(element, makeAttr(j, `display${suffix}`, literal));
72
+ }
73
+ }
74
+ else if (key === 'textSize' && literal !== undefined) {
75
+ addAttr(element, makeAttr(j, `textSize${suffix}`, String(literal)));
76
+ }
77
+ else if (key === 'textAlign' && typeof literal === 'string') {
78
+ addAttr(element, makeAttr(j, `textAlign${suffix}`, TEXT_ALIGN_MAP[literal] ?? literal));
79
+ }
80
+ else if (key === 'invisible' && literal === true) {
81
+ addAttr(element, makeAttr(j, `visibility${suffix}`, 'invisible'));
82
+ }
83
+ else if (key === 'only') {
84
+ remaining.push(prop);
85
+ addTodo(ctx, path, 'responsive', `\`${name}.only\` (-only helper classes) has no bestax equivalent; use className`);
86
+ continue;
87
+ }
88
+ else if (kind === 'column' && (key === 'size' || key === 'offset')) {
89
+ // Column sizes accept numbers and named strings alike; reuse the node.
90
+ const target = `${key}${suffix}`;
91
+ addAttr(element, j.jsxAttribute(j.jsxIdentifier(target), j.jsxExpressionContainer(prop.value)));
92
+ }
93
+ else if (kind === 'column' && key === 'narrow' && literal === true) {
94
+ addAttr(element, makeAttr(j, `isNarrow${suffix}`));
95
+ }
96
+ else if (kind === 'columns' && key === 'gap') {
97
+ addAttr(element, j.jsxAttribute(j.jsxIdentifier(`gap${suffix}`), j.jsxExpressionContainer(prop.value)));
98
+ }
99
+ else {
100
+ remaining.push(prop);
101
+ addTodo(ctx, path, 'responsive', `\`${name}.${String(key)}\` could not be flattened to a bestax per-viewport prop`);
102
+ continue;
103
+ }
104
+ }
105
+ if (remaining.length === 0) {
106
+ removeAttr(element, attr);
107
+ }
108
+ else {
109
+ objectExpr.properties = remaining;
110
+ }
111
+ ctx.dirty = true;
112
+ }
113
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Structural handlers for conversions a rename table can't express: targets
3
+ * chosen by prop values (Level.Side align), child rewrites (Icon <i> parsing,
4
+ * Tabs list wrapping), element replacement (Form.Help → plain <p>), and
5
+ * container unwrapping (Table.Container).
6
+ *
7
+ * A handler may return a `target` override for the rename step, or mark the
8
+ * element `replaced` when it substituted the node itself.
9
+ */
10
+ import type { ASTPath } from 'jscodeshift';
11
+ import { type TransformContext } from './jsx-utils.js';
12
+ export interface SpecialResult {
13
+ /** Override the mapping's `target` for the rename step. */
14
+ target?: string;
15
+ /** The node was replaced outright — skip rename and prop passes. */
16
+ replaced?: boolean;
17
+ /** Prop names the handler consumed; skipped by the later prop passes. */
18
+ handledProps?: string[];
19
+ }
20
+ export declare function runSpecial(name: string, ctx: TransformContext, path: ASTPath<any>, element: any): SpecialResult;
21
+ /** Responsive-flattening kinds keyed by mapping special names. */
22
+ export declare const RESPONSIVE_KINDS: Record<string, 'columns' | 'column'>;
23
+ //# sourceMappingURL=specials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAUL,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;AA6wBD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf;AAED,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAGjE,CAAC"}