bestax-migrate 2.29.2 → 2.31.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.
package/README.md CHANGED
@@ -88,7 +88,7 @@ Run it from your app root. `--param paths="src lib"` (default `src`) and `--para
88
88
  | Flag | Description |
89
89
  | -------------------- | ---------------------------------------------------------------------------------------------- |
90
90
  | `--dry`, `-d` | Report what would change without writing files |
91
- | `--print`, `-p` | Print transformed sources to stdout |
91
+ | `--print`, `-p` | Print transformed sources to stdout, still writing them unless `--dry` is set |
92
92
  | `--extensions`, `-e` | File extensions to include in a folder (default `js,jsx,ts,tsx,scss,sass`; `html` for pages) |
93
93
  | `--css <mode>` | Stylesheet target: `bestax`, `bulma`, or `keep` (default `bestax`; `keep` for `bulma-classes`) |
94
94
  | `--no-deps` | Skip updating package.json dependencies |
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAIV,eAAe,EAEhB,MAAM,YAAY,CAAC;AA2BpB;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,KAAK,GAAE,SAAS,MAAM,EAAO,GAC5B,MAAM,EAAE,CAwBV;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAkB5D;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgDlD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsBvD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAEpE;AA2QD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,KAAK,EACT,KAAK,GAAE,QAAwB,EAC/B,MAAM,GAAE,QAAyB,EAGjC,aAAa,GAAE,OAAO,eAAiC,GACtD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,OAAO,GAAG,SAAS,EACzB,EAAE,EAAE,KAAK,EACT,aAAa,GAAE,CAAC,EAAE,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAA0B,GAC7E,OAAO,CAAC,IAAI,CAAC,CAqBf;AAYD,wBAAgB,SAAS,CACvB,EAAE,GAAE,KAAkD,GACrD,OAAO,CA+IT"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAIV,eAAe,EAEhB,MAAM,YAAY,CAAC;AA2BpB;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,KAAK,GAAE,SAAS,MAAM,EAAO,GAC5B,MAAM,EAAE,CAwBV;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAkB5D;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgDlD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsBvD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAEpE;AA2QD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,KAAK,EACT,KAAK,GAAE,QAAwB,EAC/B,MAAM,GAAE,QAAyB,EAGjC,aAAa,GAAE,OAAO,eAAiC,GACtD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,OAAO,GAAG,SAAS,EACzB,EAAE,EAAE,KAAK,EACT,aAAa,GAAE,CAAC,EAAE,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAA0B,GAC7E,OAAO,CAAC,IAAI,CAAC,CAqBf;AAYD,wBAAgB,SAAS,CACvB,EAAE,GAAE,KAAkD,GACrD,OAAO,CAmJT"}
package/dist/cli.js CHANGED
@@ -524,7 +524,7 @@ export function createCLI(io = { log: console.log, error: console.error }) {
524
524
  .argument('<source>', `library to migrate from (${sourceNames().join(', ')})`)
525
525
  .argument('<paths...>', 'files or directories to transform')
526
526
  .option('-d, --dry', 'dry run — report what would change without writing', false)
527
- .option('-p, --print', 'print transformed sources to stdout', false)
527
+ .option('-p, --print', 'print transformed sources to stdout (still writes them unless --dry)', false)
528
528
  .option('-e, --extensions <list>', 'comma-separated file extensions to include in a folder (html for HTML pages)', 'js,jsx,ts,tsx,scss,sass')
529
529
  .option('--css <mode>', `stylesheet target: ${CSS_MODES.join(', ')} (default bestax; keep for bulma-classes)`)
530
530
  .option('--no-deps', 'skip updating package.json dependencies')
@@ -52,6 +52,33 @@ export interface Modifier {
52
52
  readonly name: string;
53
53
  readonly value: string;
54
54
  };
55
+ /**
56
+ * Off the tags in `tagIn`, where the class stays a class, the prop that
57
+ * sizes the element the same without picking its tag (`textSize`, whose
58
+ * `is-size-4` Bulma sizes as it does `Title`'s `is-4`). The MCP lookup reads
59
+ * it, and the truth e2e holds it to Bulma's stylesheet; the codemod writes
60
+ * it nowhere, with no TODO either, since its class differs.
61
+ */
62
+ readonly offTag?: PropWrite;
63
+ /**
64
+ * Another of the root's modifiers whose prop this one writes another value
65
+ * of, and that value renders that modifier's class too (`Field`'s
66
+ * `hasAddons="centered"` renders `has-addons` beside `has-addons-centered`).
67
+ * The class converts only beside that one, the two as the one value, and
68
+ * stays a class on its own. Beside it, `tagIn` and `needsAttr` hold as they
69
+ * do for any modifier.
70
+ */
71
+ readonly beside?: string;
72
+ /**
73
+ * The tag the target renders with this class's prop and no `as`, in place
74
+ * of the root's `tag` (`Image` puts a ratio on a <figure>), so the element
75
+ * converts with `as` only on another tag. The planner's tag check, which
76
+ * comes before every refusal, reads it, and the render truth test holds it
77
+ * to one of the tags it renders the root on. Only one such class converts
78
+ * on an element; a second stays a class, the way a second class for a prop
79
+ * already written does.
80
+ */
81
+ readonly rendersTag?: string;
55
82
  }
56
83
  /**
57
84
  * - `mapped`: converts to `target`.
@@ -126,6 +153,14 @@ export interface Absorbs {
126
153
  readonly to: string;
127
154
  readonly beside: string;
128
155
  }>>;
156
+ /**
157
+ * The bestax component that takes a `<label>` beside the child as its own
158
+ * `label` (`Select`, which renders a `Field` and a `Control` around the
159
+ * target, and so takes one only outside a `Field` or `Control`), for the
160
+ * TODO on an element holding one: the target renders no label, so the
161
+ * element stays markup.
162
+ */
163
+ readonly label?: string;
129
164
  }
130
165
  /** How a target that renders a glyph from props reads one (`Icon`). */
131
166
  export interface ReadsGlyph {
@@ -351,6 +386,14 @@ export interface RootEntry {
351
386
  * no prop for them.
352
387
  */
353
388
  readonly omits?: Readonly<Record<string, string>>;
389
+ /**
390
+ * How to keep this class on an element another root converts, where
391
+ * wrapping or nesting its component is not always the answer: `.container`
392
+ * there is often only centering the element, which `mx="auto"` does. For
393
+ * that element's TODO and the MCP lookup, which otherwise say to wrap or
394
+ * nest it.
395
+ */
396
+ readonly onAnother?: string;
354
397
  /**
355
398
  * Bulma styles this root's modifiers, and the classes it omits, only on
356
399
  * the element that carries the root itself (`.image.is-64x64`), so on an
@@ -358,7 +401,25 @@ export interface RootEntry {
358
401
  */
359
402
  readonly modifiersNeedRoot?: boolean;
360
403
  }
404
+ /**
405
+ * Whether a root's target renders this tag: the one it renders by itself (or
406
+ * `renders`, the one the element's classes pick: a heading's size, an
407
+ * `Image` ratio's <figure>), or one its `as` takes. A root that doesn't loses
408
+ * to one that does on the same element.
409
+ */
410
+ export declare function reachesTag(entry: RootEntry, tag: string, renders?: string): boolean;
411
+ /**
412
+ * How well a root fits an element's tag, for picking one of two: 2 when its
413
+ * target renders the tag with no `as` (`Hero`'s <section>, or `renders`, the
414
+ * tag the element's classes pick: an `Image` ratio's <figure>), 1 when it
415
+ * reaches it only through `as` (`Container`'s <section>), 0 when it can't
416
+ * render it. The higher wins, so `<section className="hero container">` is a
417
+ * `Hero`, and `<div className="media-left image is-1by1">` no `Image`, which
418
+ * that ratio puts on a <figure>.
419
+ */
420
+ export declare function tagFit(entry: RootEntry, tag: string, renders?: string): number;
361
421
  export declare const COLORS: readonly ["primary", "link", "info", "success", "warning", "danger", "black", "black-bis", "black-ter", "grey-darker", "grey-dark", "grey", "grey-light", "grey-lighter", "white", "white-bis", "white-ter", "light", "dark"];
422
+ export declare const COLOR_SHADES: readonly ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "invert", "light", "dark", "soft", "bold", "on-scheme"];
362
423
  export declare const SIZES: readonly ["0", "1", "2", "3", "4", "5", "6", "auto"];
363
424
  export declare const TEXT_SIZES: readonly ["1", "2", "3", "4", "5", "6", "7"];
364
425
  export declare const ALIGNMENTS: readonly ["centered", "justified", "left", "right"];
@@ -391,9 +452,16 @@ export declare const ROOTS: Readonly<Record<string, RootEntry>>;
391
452
  */
392
453
  export declare const PLACED: Readonly<Record<string, RootEntry>>;
393
454
  /**
394
- * Which root wins when an element carries two (`column box`): layout before
395
- * surface, so the element keeps the role that decides where it sits. The
396
- * other root stays in `className`, which renders the same either way.
455
+ * Which root wins when an element carries two (`column box`) that fit its tag
456
+ * alike: layout before surface, so the element keeps the role that decides
457
+ * where it sits. A better fit beats a higher place here (`tagFit`): `Image`
458
+ * takes a `<figure className="image container">`, which `Container` can't
459
+ * render, and `Hero` a `<section className="hero container">`, whose tag is
460
+ * its own and only reached through `as` by `Container`. The fit is to the
461
+ * tag the element's classes make a root render, so `Image` with a ratio fits
462
+ * a <figure> as its own and a <div> only through `as`. The other root stays
463
+ * in `className`, which renders the same either way, and the element gets a
464
+ * TODO naming its component.
397
465
  */
398
466
  export declare const PRECEDENCE: readonly string[];
399
467
  /**
@@ -445,6 +513,11 @@ export type HelperGroup = 'text-color' | 'background' | 'spacing' | 'gap' | 'typ
445
513
  export interface HelperToken {
446
514
  readonly group: HelperGroup;
447
515
  readonly write: PropWrite;
516
+ /**
517
+ * A second prop the class needs beside `write`, which it converts only
518
+ * with (a color shade's `colorShade` beside its color).
519
+ */
520
+ readonly also?: PropWrite;
448
521
  }
449
522
  export declare const HELPER_TOKENS: ReadonlyMap<string, HelperToken>;
450
523
  /** Every helper prop name, for the attribute-collision check. */
@@ -1 +1 @@
1
- {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,31 @@
21
21
  export function inTagSet(set, tag) {
22
22
  return 'on' in set ? set.on.includes(tag) : !set.except.includes(tag);
23
23
  }
24
+ /**
25
+ * Whether a root's target renders this tag: the one it renders by itself (or
26
+ * `renders`, the one the element's classes pick: a heading's size, an
27
+ * `Image` ratio's <figure>), or one its `as` takes. A root that doesn't loses
28
+ * to one that does on the same element.
29
+ */
30
+ export function reachesTag(entry, tag, renders = entry.tag) {
31
+ if (tag === renders || entry.as === 'any')
32
+ return true;
33
+ return entry.as?.includes(tag) ?? false;
34
+ }
35
+ /**
36
+ * How well a root fits an element's tag, for picking one of two: 2 when its
37
+ * target renders the tag with no `as` (`Hero`'s <section>, or `renders`, the
38
+ * tag the element's classes pick: an `Image` ratio's <figure>), 1 when it
39
+ * reaches it only through `as` (`Container`'s <section>), 0 when it can't
40
+ * render it. The higher wins, so `<section className="hero container">` is a
41
+ * `Hero`, and `<div className="media-left image is-1by1">` no `Image`, which
42
+ * that ratio puts on a <figure>.
43
+ */
44
+ export function tagFit(entry, tag, renders = entry.tag) {
45
+ if (tag === renders)
46
+ return 2;
47
+ return reachesTag(entry, tag, renders) ? 1 : 0;
48
+ }
24
49
  // ---- Value vocabularies (held to @allxsmith/bestax-bulma/constants) --------
25
50
  export const COLORS = [
26
51
  'primary',
@@ -43,6 +68,34 @@ export const COLORS = [
43
68
  'light',
44
69
  'dark',
45
70
  ];
71
+ export const COLOR_SHADES = [
72
+ '00',
73
+ '05',
74
+ '10',
75
+ '15',
76
+ '20',
77
+ '25',
78
+ '30',
79
+ '35',
80
+ '40',
81
+ '45',
82
+ '50',
83
+ '55',
84
+ '60',
85
+ '65',
86
+ '70',
87
+ '75',
88
+ '80',
89
+ '85',
90
+ '90',
91
+ '95',
92
+ 'invert',
93
+ 'light',
94
+ 'dark',
95
+ 'soft',
96
+ 'bold',
97
+ 'on-scheme',
98
+ ];
46
99
  export const SIZES = ['0', '1', '2', '3', '4', '5', '6', 'auto'];
47
100
  export const TEXT_SIZES = ['1', '2', '3', '4', '5', '6', '7'];
48
101
  export const ALIGNMENTS = ['centered', 'justified', 'left', 'right'];
@@ -269,6 +322,28 @@ function perViewport(prefix, values, prop, viewports) {
269
322
  function flags(map) {
270
323
  return Object.fromEntries(Object.entries(map).map(([token, prop]) => [token, flag(prop)]));
271
324
  }
325
+ /**
326
+ * `Title`'s and `SubTitle`'s `is-1` to `is-6`: `size`, exact only on the
327
+ * heading it names (or a <p>), since the size picks the heading. On any
328
+ * other tag the class stays, and `textSize` sizes it the same.
329
+ */
330
+ function headingSizes() {
331
+ return Object.fromEntries(['1', '2', '3', '4', '5', '6'].map(n => [
332
+ `is-${n}`,
333
+ {
334
+ writes: [{ prop: 'size', value: n }],
335
+ tagIn: [`h${n}`, 'p'],
336
+ offTag: { prop: 'textSize', value: n },
337
+ },
338
+ ]));
339
+ }
340
+ /** The same modifiers, each converting only beside `other`. */
341
+ function beside(other, modifiers) {
342
+ return Object.fromEntries(Object.entries(modifiers).map(([token, modifier]) => [
343
+ token,
344
+ { ...modifier, beside: other },
345
+ ]));
346
+ }
272
347
  const BASE = {
273
348
  status: 'mapped',
274
349
  textColor: 'textColor',
@@ -700,6 +775,9 @@ export const ROOTS = {
700
775
  'breakpoint',
701
776
  'isMax',
702
777
  ],
778
+ // On another root's element it is often there only to center it (a sized
779
+ // `.image`), which `mx="auto"` does and nothing else `.container` sets.
780
+ onAnother: 'where it is only there to center this element, `mx="auto"` centers it, and otherwise wrap the element in a `Container`; either way drop the class, then check the layout',
703
781
  },
704
782
  content: {
705
783
  ...BASE,
@@ -743,8 +821,6 @@ export const ROOTS = {
743
821
  ...BASE,
744
822
  target: 'Field',
745
823
  tag: 'div',
746
- // `has-addons-centered`, `is-grouped-right` and the like stay classes:
747
- // the prop values that render them render `has-addons` too.
748
824
  modifiers: {
749
825
  ...flags({
750
826
  'is-horizontal': 'horizontal',
@@ -754,6 +830,11 @@ export const ROOTS = {
754
830
  // `grouped` renders `is-grouped` for `true` and its three layouts, and
755
831
  // for nothing else truthy.
756
832
  'is-grouped': { writes: [{ prop: 'grouped' }], onlyTrue: true },
833
+ // The prop values that render `has-addons-centered`, `is-grouped-right`
834
+ // and the like render `has-addons` or `is-grouped` too, so each converts
835
+ // only beside that class, and stays a class on its own.
836
+ ...beside('has-addons', tokens('has-addons-', ['centered', 'right'], 'hasAddons')),
837
+ ...beside('is-grouped', tokens('is-grouped-', ['centered', 'right', 'multiline'], 'grouped')),
757
838
  },
758
839
  wrapsChildren: {
759
840
  in: 'field-body',
@@ -941,6 +1022,7 @@ export const ROOTS = {
941
1022
  }),
942
1023
  pairs: { multiple: 'is-multiple' },
943
1024
  renames: { size: { to: 'multipleSize', beside: 'multiple' } },
1025
+ label: 'Select',
944
1026
  },
945
1027
  numberAttrs: ['multipleSize'],
946
1028
  adoptsIdFrom: ['Field'],
@@ -1198,10 +1280,7 @@ export const ROOTS = {
1198
1280
  as: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'],
1199
1281
  sizeDrivesTag: true,
1200
1282
  modifiers: {
1201
- ...Object.fromEntries(['1', '2', '3', '4', '5', '6'].map(n => [
1202
- `is-${n}`,
1203
- { writes: [{ prop: 'size', value: n }], tagIn: [`h${n}`, 'p'] },
1204
- ])),
1283
+ ...headingSizes(),
1205
1284
  ...flags({ 'has-skeleton': 'hasSkeleton' }),
1206
1285
  },
1207
1286
  ownProps: ['size', 'as', 'hasSkeleton', 'textColor', 'bgColor'],
@@ -1280,10 +1359,7 @@ export const ROOTS = {
1280
1359
  as: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'],
1281
1360
  sizeDrivesTag: true,
1282
1361
  modifiers: {
1283
- ...Object.fromEntries(['1', '2', '3', '4', '5', '6'].map(n => [
1284
- `is-${n}`,
1285
- { writes: [{ prop: 'size', value: n }], tagIn: [`h${n}`, 'p'] },
1286
- ])),
1362
+ ...headingSizes(),
1287
1363
  ...flags({ 'is-spaced': 'isSpaced', 'has-skeleton': 'hasSkeleton' }),
1288
1364
  },
1289
1365
  ownProps: ['size', 'isSpaced', 'as', 'hasSkeleton', 'textColor', 'bgColor'],
@@ -1442,42 +1518,45 @@ export const ROOTS = {
1442
1518
  ownProps: ['textColor', 'bgColor', 'color', 'iconProps', 'items'],
1443
1519
  },
1444
1520
  // `Image` renders `.image` and the `<img>` inside it together, from `src`
1445
- // and `alt`. A ratio stays a class: as `size`, it adds `has-ratio` too.
1521
+ // and `alt`. A ratio as `size` puts it on a <figure> unless `as` says
1522
+ // otherwise.
1446
1523
  image: {
1447
1524
  ...BASE,
1448
1525
  target: 'Image',
1449
1526
  tag: 'div',
1450
1527
  as: ['div', 'figure', 'p'],
1451
- modifiers: tokens('is-', [
1452
- '16x16',
1453
- '24x24',
1454
- '32x32',
1455
- '48x48',
1456
- '64x64',
1457
- '96x96',
1458
- '128x128',
1459
- 'square',
1460
- ], 'size'),
1461
- omits: Object.fromEntries([
1462
- '1by1',
1463
- '5by4',
1464
- '4by3',
1465
- '3by2',
1466
- '5by3',
1467
- '16by9',
1468
- '2by1',
1469
- '3by1',
1470
- '4by5',
1471
- '3by4',
1472
- '2by3',
1473
- '3by5',
1474
- '9by16',
1475
- '1by2',
1476
- '1by3',
1477
- ].map(ratio => [
1478
- `is-${ratio}`,
1479
- '`size` renders `has-ratio` beside it as well',
1480
- ])),
1528
+ modifiers: {
1529
+ ...tokens('is-', [
1530
+ '16x16',
1531
+ '24x24',
1532
+ '32x32',
1533
+ '48x48',
1534
+ '64x64',
1535
+ '96x96',
1536
+ '128x128',
1537
+ 'square',
1538
+ ], 'size'),
1539
+ ...Object.fromEntries([
1540
+ '1by1',
1541
+ '5by4',
1542
+ '4by3',
1543
+ '3by2',
1544
+ '5by3',
1545
+ '16by9',
1546
+ '2by1',
1547
+ '3by1',
1548
+ '4by5',
1549
+ '3by4',
1550
+ '2by3',
1551
+ '3by5',
1552
+ '9by16',
1553
+ '1by2',
1554
+ '1by3',
1555
+ ].map(ratio => [
1556
+ `is-${ratio}`,
1557
+ { ...set('size', ratio), rendersTag: 'figure' },
1558
+ ])),
1559
+ },
1481
1560
  modifiersNeedRoot: true,
1482
1561
  absorbs: {
1483
1562
  tag: 'img',
@@ -1910,9 +1989,16 @@ export const PLACED = {
1910
1989
  },
1911
1990
  };
1912
1991
  /**
1913
- * Which root wins when an element carries two (`column box`): layout before
1914
- * surface, so the element keeps the role that decides where it sits. The
1915
- * other root stays in `className`, which renders the same either way.
1992
+ * Which root wins when an element carries two (`column box`) that fit its tag
1993
+ * alike: layout before surface, so the element keeps the role that decides
1994
+ * where it sits. A better fit beats a higher place here (`tagFit`): `Image`
1995
+ * takes a `<figure className="image container">`, which `Container` can't
1996
+ * render, and `Hero` a `<section className="hero container">`, whose tag is
1997
+ * its own and only reached through `as` by `Container`. The fit is to the
1998
+ * tag the element's classes make a root render, so `Image` with a ratio fits
1999
+ * a <figure> as its own and a <div> only through `as`. The other root stays
2000
+ * in `className`, which renders the same either way, and the element gets a
2001
+ * TODO naming its component.
1916
2002
  */
1917
2003
  export const PRECEDENCE = [
1918
2004
  'columns',
@@ -2077,6 +2163,39 @@ function helperFlag(group, token, prop) {
2077
2163
  }
2078
2164
  /** The color helpers also take the two CSS keywords. */
2079
2165
  const HELPER_COLORS = [...COLORS, 'inherit', 'current'];
2166
+ /**
2167
+ * The colors Bulma writes shade helpers for: its own palette, but `text`,
2168
+ * which bestax's color props don't take.
2169
+ */
2170
+ const SHADED_COLORS = [
2171
+ 'primary',
2172
+ 'link',
2173
+ 'info',
2174
+ 'success',
2175
+ 'warning',
2176
+ 'danger',
2177
+ 'black',
2178
+ 'white',
2179
+ 'light',
2180
+ 'dark',
2181
+ ];
2182
+ /**
2183
+ * `has-text-{color}-{shade}` → the color prop and `colorShade`, which render
2184
+ * it together; `has-background-…` the same with `backgroundColorShade`. The
2185
+ * color prop is a placeholder the planner swaps for the target's own, as for
2186
+ * the plain color helpers. A class with no single shade to write (`-100`,
2187
+ * `-30-invert`) is not one of these, and stays a class.
2188
+ */
2189
+ function shadeTokens(group, prefix, prop, shadeProp) {
2190
+ return SHADED_COLORS.flatMap(color => COLOR_SHADES.map((shade) => [
2191
+ `${prefix}${color}-${shade}`,
2192
+ {
2193
+ group,
2194
+ write: { prop, value: color },
2195
+ also: { prop: shadeProp, value: shade },
2196
+ },
2197
+ ]));
2198
+ }
2080
2199
  const SPACING_PROPS = [
2081
2200
  'm',
2082
2201
  'mt',
@@ -2097,6 +2216,8 @@ export const HELPER_TOKENS = new Map([
2097
2216
  // Colors: the prop is a placeholder the planner swaps for the target's own.
2098
2217
  ...helperTokens('text-color', 'has-text-', HELPER_COLORS, 'textColor'),
2099
2218
  ...helperTokens('background', 'has-background-', HELPER_COLORS, 'bgColor'),
2219
+ ...shadeTokens('text-color', 'has-text-', 'textColor', 'colorShade'),
2220
+ ...shadeTokens('background', 'has-background-', 'bgColor', 'backgroundColorShade'),
2100
2221
  ...SPACING_PROPS.flatMap(prop => helperTokens('spacing', `${prop}-`, SIZES, prop)),
2101
2222
  // Bulma 0.9's, as the v1 helper that replaced each (`REPLACED_IN_V1`).
2102
2223
  ['is-marginless', { group: 'spacing', write: { prop: 'm', value: '0' } }],
@@ -2179,7 +2300,7 @@ export const HELPER_PROPS = new Set([
2179
2300
  */
2180
2301
  export const PASSTHROUGH = [
2181
2302
  {
2182
- why: 'a color shade, a scheme color or a palette; shades stay as classes',
2303
+ why: 'a color shade with no single shade for `colorShade` or `backgroundColorShade` to write (`-100`, or one with `-invert` on the end), a shade of the `text` color, a scheme color or a palette',
2183
2304
  match: /^(?:has-(?:text|background)-[a-z]+(?:-[a-z]+)?-(?:\d{2,3}|invert|light|dark|soft|bold|on-scheme)(?:-invert)?|has-(?:text|background)-text|has-background|is-palette-[a-z]+|is-(?:bold|soft))$/,
2184
2305
  },
2185
2306
  {
@@ -63,6 +63,13 @@ export interface ElementFacts {
63
63
  * component). What an entry that `countsChildren` reads.
64
64
  */
65
65
  childElements?: readonly ChildFacts[];
66
+ /**
67
+ * The element's children as plain HTML elements, read as `childElements`
68
+ * is, when nothing else beside them renders but spaces (`{" "}` between
69
+ * them); left out when `childElements` is there. What the TODO on an
70
+ * element holding a <label> beside the child its target renders reads.
71
+ */
72
+ spacedElements?: readonly ChildFacts[];
66
73
  /** The bestax components already in the file inside this element. */
67
74
  bestaxInside?: readonly string[];
68
75
  /** The bestax components already in the file around this element. */
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@
14
14
  * way. And a Bulma 0.9 helper v1 removed (`REPLACED_IN_V1`), which styles
15
15
  * nothing under v1, converts as the v1 helper that does its job.
16
16
  */
17
- import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, modifiesRoot, numberAttrsOf, placedFor, PRECEDENCE, replacedBy, rootFor, rootItNeeds, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
17
+ import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, modifiesRoot, numberAttrsOf, placedFor, PRECEDENCE, reachesTag, replacedBy, rootFor, rootItNeeds, tagFit, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
18
18
  import { glyphProps, readDrawnGlyph, readGlyph, readHiddenGlyph, } from './glyph.js';
19
19
  import { aTag } from '../_shared/articles.js';
20
20
  import { ruleId } from './rules.js';
@@ -54,13 +54,6 @@ function precedence(token) {
54
54
  function rootLabel(tokens) {
55
55
  return tokens.find(token => rootFor(token)?.status === 'mapped') ?? 'button';
56
56
  }
57
- /**
58
- * Whether the target renders this tag: the one it renders by itself (or the
59
- * heading its size picks), or one its `as` takes.
60
- */
61
- function reachesTag(entry, tag, renders = entry.tag) {
62
- return (tag === renders || entry.as === 'any' || (entry.as?.includes(tag) ?? false));
63
- }
64
57
  function tagsItReaches(entry) {
65
58
  if (entry.as === 'any')
66
59
  return 'any tag through `as`';
@@ -68,6 +61,50 @@ function tagsItReaches(entry) {
68
61
  return entry.as.map(tag => `<${tag}>`).join(', ');
69
62
  return `only <${entry.tag}>`;
70
63
  }
64
+ /**
65
+ * A TODO for each other component class on an element that converts
66
+ * (`columns box`). The class stays in `className`, which renders the same,
67
+ * but on a bestax component it is raw Bulma markup the lint rule reports, so
68
+ * each says which root won and why, and how to keep what the class does.
69
+ * `rendered` holds the tag the element's classes make each root's target
70
+ * render with no `as`, for the roots the planner picked from.
71
+ */
72
+ function secondComponents(carried, fixed, root, target, tag, rendered) {
73
+ return carried.flatMap(token => {
74
+ const other = rootFor(token);
75
+ if (token === root || other?.status !== 'mapped')
76
+ return [];
77
+ const name = other.target;
78
+ if (name === target)
79
+ return [];
80
+ const fitsBetter = root !== undefined &&
81
+ tagFit(rootFor(root), tag, rendered.get(root)) >
82
+ tagFit(other, tag, rendered.get(token));
83
+ // The tag is the target's own, or one the element's classes pick.
84
+ const fits = root !== undefined && rootFor(root).tag === tag
85
+ ? `${aTag(tag)} is \`${target}\`'s own element`
86
+ : `\`${target}\` renders ${aTag(tag)} with these classes and no \`as\``;
87
+ const why = !fixed.includes(token)
88
+ ? `since \`.${token}\` is there only when its condition holds, and the codemod picks from the classes the element always carries`
89
+ : root === undefined
90
+ ? 'since an item of a list converts by where it sits'
91
+ : !reachesTag(other, tag, rendered.get(token))
92
+ ? `since \`${name}\` renders ${tagsItReaches(other)}, not ${aTag(tag)}`
93
+ : fitsBetter
94
+ ? `since ${fits}, and \`${name}\` renders one only through \`as\``
95
+ : precedence(root) < precedence(token)
96
+ ? `since the codemod ranks \`.${root}\` first, putting layout and parts ahead of surfaces`
97
+ : `since \`.${root}\` comes first on the element`;
98
+ const advice = other.onAnother ??
99
+ `to use \`${name}\`, give it an element of its own around or inside this one and drop the class, then check the layout, since two elements space differently from one`;
100
+ return [
101
+ {
102
+ rule: ruleId('second-component', name),
103
+ message: `\`.${token}\` is bestax \`${name}\`'s class too, and an element converts to one component: \`${target}\` here, ${why}, so \`.${token}\` stays in its \`className\`, which renders the same; ${advice}`,
104
+ },
105
+ ];
106
+ });
107
+ }
71
108
  /**
72
109
  * Every class the element may carry: its fixed ones, and any a condition
73
110
  * adds, which the element has to be right with as well as without.
@@ -151,11 +188,21 @@ function planElement(facts) {
151
188
  : tokens.find(token => rootFor(token)?.status === 'fold');
152
189
  if (wrapper)
153
190
  return planFold(facts, wrapper, todos);
154
- const root = placed
155
- ? undefined
191
+ // Of two roots, the one that fits the element's tag best wins (the tag the
192
+ // element's classes make its target render with no `as`, then one `as`
193
+ // reaches), and the table's precedence decides a tie. So an `Image` ratio,
194
+ // which puts it on a <figure>, fits a <div> only through `as`.
195
+ const roots = placed
196
+ ? []
156
197
  : tokens
157
198
  .filter(token => rootFor(token)?.status === 'mapped')
158
- .sort((a, b) => precedence(a) - precedence(b))[0];
199
+ .sort((a, b) => precedence(a) - precedence(b));
200
+ const rendered = new Map(roots.map(token => [
201
+ token,
202
+ rendersWith(rootFor(token), tokens, tag, token, facts.attributes),
203
+ ]));
204
+ const fit = (token) => tagFit(rootFor(token), tag, rendered.get(token));
205
+ const root = roots.reduce((best, token) => best === undefined || fit(token) > fit(best) ? token : best, undefined);
159
206
  let entry;
160
207
  if (placed) {
161
208
  entry = placed;
@@ -189,12 +236,10 @@ function planElement(facts) {
189
236
  // On a tag the target can't render, the tag is the work that comes first:
190
237
  // any other refusal would ask for work (an attribute added or dropped, a
191
238
  // child moved) that a re-run then refuses on the tag anyway.
192
- let renders = entry.tag;
193
- if (entry.sizeDrivesTag && tag !== 'p') {
194
- const size = propsFrom(entry, tokens, tag, root, facts.attributes).writes.get('size');
195
- if (size !== undefined)
196
- renders = `h${size}`;
197
- }
239
+ // What the classes write picks the tag the target renders with no `as`
240
+ // (`rendersWith`), as it did when the root was picked.
241
+ const renders = (root && rendered.get(root)) ??
242
+ rendersWith(entry, tokens, tag, root, facts.attributes);
198
243
  let as;
199
244
  if (renders !== tag) {
200
245
  if (!reachesTag(entry, tag, renders)) {
@@ -517,6 +562,7 @@ function planElement(facts) {
517
562
  if (entry.classNameReplaces && (rest.length > 0 || conditionalStays)) {
518
563
  return refuse('attr', 'className', `bestax \`${target}\` writes a \`className\` it's given in place of \`.${root}\`, so this converts only with no other class; keep it as markup`);
519
564
  }
565
+ todos.push(...secondComponents(carried, tokens, root, target, tag, rendered));
520
566
  // A glyph the target renders from props takes the place of the only child.
521
567
  const glyph = moved ?? (entry.readsGlyph ? readGlyph(facts.soleChild) : undefined);
522
568
  return {
@@ -831,6 +877,7 @@ function buildIcons(children, target) {
831
877
  */
832
878
  function propsFrom(entry, tokens, tag, root, attributes) {
833
879
  const numbers = [];
880
+ let rendersTag;
834
881
  // What the root itself needs comes first, so no class can take its prop.
835
882
  const writes = new Map((entry.writes ?? []).map(write => [write.prop, write.value ?? true]));
836
883
  /** The tokens each written prop came from, so a group rule can undo it. */
@@ -841,11 +888,24 @@ function propsFrom(entry, tokens, tag, root, attributes) {
841
888
  ...tokens.filter(token => !replacedBy(token)),
842
889
  ...tokens.filter(token => replacedBy(token)),
843
890
  ];
844
- for (const token of claiming) {
891
+ // A class that converts only beside another (`has-addons-centered`) goes
892
+ // first, so the value it writes takes the prop ahead of that one's flag and
893
+ // renders both classes. On its own it stays a class. Neither is ever a
894
+ // removed class, so the two orders compose.
895
+ const paired = (token) => {
896
+ const other = modifierFor(entry, token)?.beside;
897
+ return other !== undefined && tokens.includes(other);
898
+ };
899
+ for (const token of [
900
+ ...claiming.filter(paired),
901
+ ...claiming.filter(token => !paired(token)),
902
+ ]) {
845
903
  if (converted.has(token))
846
904
  continue;
847
905
  const modifier = modifierFor(entry, token);
848
906
  if (modifier) {
907
+ if (modifier.beside && !paired(token))
908
+ continue;
849
909
  if (modifier.tagIn && !modifier.tagIn.includes(tag))
850
910
  continue;
851
911
  if (modifier.needsAttr && !attributes.has(modifier.needsAttr.name)) {
@@ -853,13 +913,20 @@ function propsFrom(entry, tokens, tag, root, attributes) {
853
913
  }
854
914
  if (modifier.writes.some(write => writes.has(write.prop)))
855
915
  continue;
916
+ // Only one class picks the tag, as only one sets a prop: a second one
917
+ // stays a class, the way a second size does.
918
+ if (modifier.rendersTag && rendersTag)
919
+ continue;
856
920
  for (const write of modifier.writes) {
857
921
  writes.set(write.prop, write.value ?? true);
858
922
  sourceOf.set(write.prop, token);
859
923
  if (write.numeric)
860
924
  numbers.push(write.prop);
861
925
  }
926
+ rendersTag ??= modifier.rendersTag;
862
927
  converted.add(token);
928
+ if (modifier.beside)
929
+ converted.add(modifier.beside);
863
930
  continue;
864
931
  }
865
932
  const helper = entry.noHelpers ? undefined : HELPER_TOKENS.get(token);
@@ -875,9 +942,17 @@ function propsFrom(entry, tokens, tag, root, attributes) {
875
942
  if (entry.helpersLeftOut && Object.hasOwn(entry.helpersLeftOut, prop)) {
876
943
  continue;
877
944
  }
945
+ // A shade renders its class only together with its color, so it
946
+ // converts only when both props are free: a shade beside a color or
947
+ // shade already written stays a class.
948
+ const also = helper.also;
949
+ if (also && writes.has(also.prop))
950
+ continue;
878
951
  writes.set(prop, helper.write.value ?? true);
879
952
  sourceOf.set(prop, token);
880
953
  groupOf.set(prop, helper.group);
954
+ if (also)
955
+ writes.set(also.prop, also.value ?? true);
881
956
  converted.add(token);
882
957
  }
883
958
  const undo = (prop) => {
@@ -910,7 +985,65 @@ function propsFrom(entry, tokens, tag, root, attributes) {
910
985
  (groupOf.has('overflowX') || groupOf.has('overflowY'))) {
911
986
  undo('overflow');
912
987
  }
913
- return { writes, converted, numbers };
988
+ return { writes, converted, numbers, rendersTag };
989
+ }
990
+ /**
991
+ * The tag a root's target renders with the element's classes and no `as`,
992
+ * from what `propsFrom` takes them as: the one class with a `rendersTag`
993
+ * (`Image`'s ratio) its tag, else the heading Title's `size` names, which
994
+ * only `as="p"` overrides, else the root's own.
995
+ */
996
+ function rendersWith(entry, tokens, tag, root, attributes) {
997
+ const picked = propsFrom(entry, tokens, tag, root, attributes);
998
+ if (picked.rendersTag)
999
+ return picked.rendersTag;
1000
+ const size = picked.writes.get('size');
1001
+ return entry.sizeDrivesTag && tag !== 'p' && size !== undefined
1002
+ ? `h${size}`
1003
+ : entry.tag;
1004
+ }
1005
+ /**
1006
+ * For an element whose children are the child its target renders and one
1007
+ * <label> beside it: where the label goes instead, when the table names a
1008
+ * component that takes one (`Select`'s `label`). Empty otherwise.
1009
+ *
1010
+ * That component renders the label in a `Field` of its own, which it renders
1011
+ * only outside one: inside a `Field` it drops `label` and `labelProps`, and
1012
+ * inside a bare `Control` it nests a `.field` in the `.control`. So inside
1013
+ * either the label stays a label of the page's, moved out beside the
1014
+ * element, or the child takes an `aria-label` in its place.
1015
+ */
1016
+ function labelBeside(facts, spec, where) {
1017
+ const children = facts.childElements ?? facts.spacedElements ?? [];
1018
+ const label = children.find(child => child.tag === 'label');
1019
+ if (!spec.label ||
1020
+ children.length !== 2 ||
1021
+ !label ||
1022
+ !children.some(child => child.tag === spec.tag)) {
1023
+ return '';
1024
+ }
1025
+ const around = (name) => facts.bestaxAround?.includes(name) ||
1026
+ facts.classesAround?.includes(name.toLowerCase());
1027
+ const inForm = around('Field')
1028
+ ? `inside a \`Field\` bestax's \`${spec.label}\` renders no label of its own and drops \`label\` and \`labelProps\``
1029
+ : around('Control')
1030
+ ? `inside a \`Control\` with no \`Field\` around it, bestax's \`${spec.label}\` renders its label in a \`.field\` of its own inside the \`.control\`, which Bulma's styles aren't written for`
1031
+ : undefined;
1032
+ if (inForm) {
1033
+ return `; the <label> beside it can't stay inside the ${where} that bestax renders, and ${inForm}, so move the <label> out beside ${where}, its \`htmlFor\` on the <${spec.tag}>'s \`id\`, or give the <${spec.tag}> an \`aria-label\` in its place, then re-run`;
1034
+ }
1035
+ // A computed `className` (`null`) is one the codemod can't read, and it
1036
+ // may be what hides the label, so it is named rather than left out. So is
1037
+ // a spread, which can carry a `className` of its own.
1038
+ const classes = label.tokens === null
1039
+ ? ', its `className`, which is computed, as `labelProps={{ className: … }}` with the same expression'
1040
+ : label.tokens?.length
1041
+ ? `, its classes as \`labelProps={{ className: '${label.tokens.join(' ')}' }}\``
1042
+ : '';
1043
+ const spread = label.hasSpread
1044
+ ? ', what its spread carries in `labelProps` too, since it can set a `className` of its own'
1045
+ : '';
1046
+ return `; the <label> beside it goes on bestax's \`${spec.label}\` instead, which renders ${where} inside a \`Field\` and a \`Control\`: the label's text as \`label\`${classes}${spread}, and \`${spec.label}\` points the label at the <${spec.tag}>'s \`id\` itself, so convert the two by hand`;
914
1047
  }
915
1048
  /** `a`, `a or b`, `a, b or c`, each in backticks. */
916
1049
  function orList(names, word = 'or') {
@@ -942,7 +1075,7 @@ function absorb(facts, where, entry, target, refuse) {
942
1075
  (next && next.tag !== after?.tag)) {
943
1076
  return refuse('children', target, after
944
1077
  ? `${itself}, and a \`${after.target}\` after it from among its children, so this element converts only around a single <${spec.tag}>, and at most one <${after.tag}> after it, with nothing else beside them`
945
- : `${itself}, so this element converts only around a single <${spec.tag}>, with nothing else beside it`);
1078
+ : `${itself}, so this element converts only around a single <${spec.tag}>, with nothing else beside it${labelBeside(facts, spec, where)}`);
946
1079
  }
947
1080
  if (next &&
948
1081
  (next.tokens !== undefined ||
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAcpC,CAAC;AAqCH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAepC,CAAC;AAqCH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
@@ -23,6 +23,7 @@ export const KINDS = new Set([
23
23
  'modifier',
24
24
  'only-child',
25
25
  'ref',
26
+ 'second-component',
26
27
  'spread',
27
28
  'tag',
28
29
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkiCvD;;;;GAIG;AACH,eAAO,MAAM,UAAU,0DAKb,CAAC;AAGX,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CAy9BpB"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA+iCvD;;;;GAIG;AACH,eAAO,MAAM,UAAU,0DAKb,CAAC;AAGX,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA89BpB"}
@@ -662,15 +662,25 @@ function childFacts(child) {
662
662
  isEmpty: (child.children ?? []).every(dropped),
663
663
  };
664
664
  }
665
+ /** A space React renders between elements: blank text, or `{" "}`. */
666
+ function space(child) {
667
+ const blank = (text) => /^[ \t\n\r]*$/.test(text);
668
+ if (child.type === 'JSXText')
669
+ return blank(child.value);
670
+ return (child.type === 'JSXExpressionContainer' &&
671
+ child.expression?.type === 'StringLiteral' &&
672
+ blank(child.expression.value));
673
+ }
665
674
  /**
666
675
  * An element's children as plain HTML elements, when that is every one
667
- * React renders; undefined when one is anything else. `more` adds what else
668
- * is known of each.
676
+ * React renders but what `skip` passes over (whitespace React drops);
677
+ * undefined when one is anything else. `more` adds what else is known of
678
+ * each.
669
679
  */
670
- function childElementsOf(element, more = () => ({})) {
680
+ function childElementsOf(element, more = () => ({}), skip = dropped) {
671
681
  const children = [];
672
682
  for (const child of element.children ?? []) {
673
- if (dropped(child))
683
+ if (skip(child))
674
684
  continue;
675
685
  const found = child.type === 'JSXElement' ? childFacts(child) : undefined;
676
686
  if (!found)
@@ -1258,6 +1268,10 @@ export default function transform(fileInfo, api, options = {}) {
1258
1268
  const className = classAttr ? staticClassName(classAttr) : '';
1259
1269
  const surrounding = around(elementPath);
1260
1270
  const sole = soleChild(element);
1271
+ const childElements = childElementsOf(element, readChild);
1272
+ const spaced = childElements
1273
+ ? undefined
1274
+ : childElementsOf(element, undefined, space);
1261
1275
  // A joiner call the codemod can read converts exactly: its fixed classes
1262
1276
  // as for a static className, and each condition on a flag as its prop.
1263
1277
  const joined = className === null
@@ -1275,7 +1289,8 @@ export default function transform(fileInfo, api, options = {}) {
1275
1289
  childTargets: childTargets(elementPath),
1276
1290
  soleChildTarget: planned.get(sole)?.conversion?.target,
1277
1291
  soleChild: sole && childFacts(sole),
1278
- childElements: childElementsOf(element, readChild),
1292
+ childElements,
1293
+ ...(spaced && { spacedElements: spaced }),
1279
1294
  bestaxInside: bestaxInside.get(element) ?? [],
1280
1295
  bestaxAround: surrounding.bestax,
1281
1296
  componentsAround: surrounding.other,
@@ -33,7 +33,7 @@ export const UNIVERSAL_PROPS = {
33
33
  backgroundColor: { rename: 'bgColor' },
34
34
  textColor: {},
35
35
  colorVariant: {
36
- todo: "no direct equivalent; use isLight (Button/Notification) or a color shade like textColor='primary-dark'",
36
+ todo: "no direct equivalent; use isLight (Button/Notification) or a color shade like bgColor='primary' backgroundColorShade='90'",
37
37
  },
38
38
  // TypographyProps
39
39
  textSize: { numberToString: true },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-migrate",
3
- "version": "2.29.2",
3
+ "version": "2.31.1",
4
4
  "description": "Codemods for migrating existing React apps from other Bulma libraries to @allxsmith/bestax-bulma",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,7 +40,7 @@
40
40
  "jscodeshift": "^17.3.0",
41
41
  "parse5": "^7.3.0",
42
42
  "property-information": "^7.2.0",
43
- "@allxsmith/bestax-bulma": "^5.40.0"
43
+ "@allxsmith/bestax-bulma": "^5.41.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@jest/globals": "^30.0.0",
@@ -78,5 +78,5 @@
78
78
  "clean": "rimraf dist",
79
79
  "release": "npx semantic-release"
80
80
  },
81
- "readme": "# bestax-migrate\n\n[![npm version](https://img.shields.io/npm/v/bestax-migrate.svg)](https://www.npmjs.com/package/bestax-migrate)\n[![npm downloads](https://img.shields.io/npm/dm/bestax-migrate.svg)](https://www.npmjs.com/package/bestax-migrate)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Socket Badge](https://badge.socket.dev/npm/package/bestax-migrate/latest)](https://socket.dev/npm/package/bestax-migrate/overview)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/allxsmith/bestax/badge)](https://scorecard.dev/viewer/?uri=github.com/allxsmith/bestax)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/14361/badge)](https://www.bestpractices.dev/projects/14361)\n[![npm provenance](https://img.shields.io/badge/npm-provenance-3fb950.svg)](https://www.npmjs.com/package/bestax-migrate#provenance)\n[![Security policy](https://img.shields.io/badge/security-policy-blue.svg)](https://github.com/allxsmith/bestax/blob/main/SECURITY.md)\n\nCodemods that migrate existing React apps to [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) — the actively maintained React component library for **Bulma v1**.\n\nCurrently supported sources:\n\n| Source | Status |\n| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |\n| [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |\n| [`rbx`](https://github.com/dfee/rbx) (v2) | ✅ Full export surface mapped (a few patterns are flagged as TODOs) |\n| [`bloomer`](https://github.com/AlgusDark/bloomer) (0.6) | ✅ All 108 exports mapped (Font Awesome 4 icons and Bulma 0.4's `Nav` are flagged) |\n| `bulma-classes`: Bulma's classes on plain JSX, no library | ✅ Converts an element only when bestax renders the same markup; the rest is flagged |\n| `bulma-classes` on HTML: static pages and templates styled with Bulma | ✅ Writes a React component beside each page; its head and scripts are flagged |\n\nPass the source as the first argument: `bestax-migrate <source> <paths…>`.\n\n## Requirements\n\n**Node.js 22 or newer.** Node 18 and 20 are both past end-of-life. On an older runtime the CLI\nexits immediately with an explicit upgrade message.\n\nThis applies only to the Node version the codemod itself runs on. It places no requirement on\nthe app being migrated — the source is read as text and is never executed.\n\n## Usage\n\n```bash\n# Preview what would change (no writes)\npnpm dlx bestax-migrate react-bulma-components src/ --dry\n# …or, for an rbx or bloomer app\npnpm dlx bestax-migrate rbx src/ --dry\npnpm dlx bestax-migrate bloomer src/ --dry\n# …or, for an app that writes Bulma's classes on plain JSX\npnpm dlx bestax-migrate bulma-classes src/ --dry\n# …or, for static HTML pages styled with Bulma: name a page, or walk a folder with -e html\n# (-e html,htm takes .htm pages too)\npnpm dlx bestax-migrate bulma-classes src/pages/login/index.html --dry\npnpm dlx bestax-migrate bulma-classes -e html src/pages/ --dry\n\n# Apply the migration\npnpm dlx bestax-migrate react-bulma-components src/\n```\n\nnpm and yarn work too: `npx bestax-migrate …` / `yarn dlx bestax-migrate …`.\n\nThe codemod uses [jscodeshift](https://github.com/facebook/jscodeshift) to:\n\n- rewrite the source library's imports to `@allxsmith/bestax-bulma` (including destructuring and namespace imports)\n- 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`)\n- convert props (`renderAs` → `as`, `loading` → `isLoading`, numeric spacing/text sizes → string unions, `textAlign=\"center\"` → `textAlign=\"centered\"`, …)\n- flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`) and bloomer's `isDisplay`/`isHidden` strings, arrays and objects (`isHidden=\"touch\"` → `visibilityTouch=\"hidden\"`)\n- for `bulma-classes`, turn raw Bulma markup into components and props (`<a className=\"button is-primary\">` → `<Button as=\"a\" color=\"primary\">`, `<p className=\"has-text-centered mt-4\">` → `<Paragraph textAlign=\"centered\" mt=\"4\">`), converting an element only when bestax renders exactly the same markup\n- for `bulma-classes` on an HTML page, write a React module beside it (`index.html` → `index.tsx`, or `.jsx` when the package isn't TypeScript) whose default export is the page's body as a component (`LoginPage`), converted as the same markup written as JSX would be. The page is never changed and an existing module is never overwritten; the head, the `<html>` and `<body>` attributes, the stylesheets and scripts it loads, and inline handlers are left as `html-*` TODOs, except that under `--css bestax` or `--css bulma` the module imports the stylesheet in place of the page's Bulma `<link>`\n- restructure patterns bestax models differently (`Table.Container`, Navbar dropdowns, `Form.Help`, icon-font children → `<Icon name=…>`)\n- 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'`\n- 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. For **bulma-classes** there is no library to remove, and by default (`--css keep`) the app's Bulma version, Sass and stylesheet imports all stay: its own Bulma already styles every class a converted element renders. `--css bestax` or `--css bulma` moves it to Bulma v1 like the other sources\n\nAnything 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), [Bulma classes](https://bestax.io/docs/guides/getting-started/migration/bulma-classes)), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:\n\n```bash\nnpx skills add https://github.com/allxsmith/bestax --skill bestax-migrate\n```\n\n### Through the Codemod Registry\n\nbestax-migrate is also in the [Codemod Registry](https://app.codemod.com/registry) as `bestax-migrate`, for teams that run their migrations through Codemod. That package runs this CLI from npm at a pinned release, which can trail the newest one:\n\n```bash\n# Preview (no writes)\nnpx codemod bestax-migrate --workflow preview --param source=react-bulma-components\n# Apply\nnpx codemod bestax-migrate --param source=react-bulma-components\n```\n\nRun it from your app root. `--param paths=\"src lib\"` (default `src`) and `--param options=\"--css keep\"` pass through to the CLI. Codemod's own `--dry-run` skips the shell step this package runs, so use the `preview` workflow for a dry run.\n\n## Options\n\n| Flag | Description |\n| -------------------- | ---------------------------------------------------------------------------------------------- |\n| `--dry`, `-d` | Report what would change without writing files |\n| `--print`, `-p` | Print transformed sources to stdout |\n| `--extensions`, `-e` | File extensions to include in a folder (default `js,jsx,ts,tsx,scss,sass`; `html` for pages) |\n| `--css <mode>` | Stylesheet target: `bestax`, `bulma`, or `keep` (default `bestax`; `keep` for `bulma-classes`) |\n| `--no-deps` | Skip updating package.json dependencies |\n\n## After the codemod\n\n1. Run your package manager's install (the codemod rewrote `package.json` but never installs)\n2. Search for `TODO(bestax-migrate)` and resolve each comment\n3. Typecheck/build and review the rendered app\n\nFull 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) · [Bulma classes migration guide](https://bestax.io/docs/guides/getting-started/migration/bulma-classes).\n\n## Hardened by default\n\nA codemod rewrites your source in place, so how it is built and published matters:\n\n- **Signed provenance** — every release carries a sigstore attestation linking the tarball to the exact commit and CI run that built it. Check the **Provenance** section on the [npm page](https://www.npmjs.com/package/bestax-migrate#provenance), or run `npm audit signatures`.\n- **npm OIDC trusted publishing** — short-lived, per-run credentials; no long-lived `NPM_TOKEN` exists to be stolen. Release commits and tags are GPG-signed.\n- **Socket.dev scans every PR** for malware, install scripts, obfuscated code, and privilege escalation before it can reach `main`.\n- **The libraries this tool migrates away from are never installed here** — source fixtures are read as text only, so no unmaintained third-party package enters the dependency tree.\n- **Dependencies are a deliberate act** — install scripts are blocked unless individually allow-listed, freshly published versions are refused for 3 days, and CI installs only what the reviewed lockfile resolves.\n- **Every GitHub Action is pinned to a full commit SHA**, and CodeQL, Dependency Review, and Dependabot run continuously alongside a high-severity `pnpm audit` gate.\n- **Layered AI review before merge** — [CodeRabbit](https://coderabbit.ai) plus an independent adversarial Claude review (a different model from the one writing AI-authored changes), on top of required green CI, an approving review, and a human merge.\n\nFull detail: [`SECURITY.md`](https://github.com/allxsmith/bestax/blob/main/SECURITY.md) · [Security guide](https://bestax.io/docs/guides/security)\n\n## Telemetry\n\n`bestax-migrate` can send one **anonymous** usage event after a successful\nrun — only if you opt in when asked (once, on an interactive terminal). The\nevent is just the run's shape — source library, CSS mode, the dry/deps flags, a\ncapped changed-file count, and per-rule TODO counts — plus the CLI version,\nNode major version, and OS platform name. Never file paths, file contents,\ncode, names, IPs, or machine IDs, and no identifier exists that could link two\nevents together. Opt out any time with `--no-telemetry`,\n`BESTAX_TELEMETRY=0`, or `DO_NOT_TRACK=1`.\n\nFull disclosure of every field and control: [Telemetry guide](https://bestax.io/docs/guides/telemetry)\n\n## License\n\nSource code licensed MIT\n"
81
+ "readme": "# bestax-migrate\n\n[![npm version](https://img.shields.io/npm/v/bestax-migrate.svg)](https://www.npmjs.com/package/bestax-migrate)\n[![npm downloads](https://img.shields.io/npm/dm/bestax-migrate.svg)](https://www.npmjs.com/package/bestax-migrate)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Socket Badge](https://badge.socket.dev/npm/package/bestax-migrate/latest)](https://socket.dev/npm/package/bestax-migrate/overview)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/allxsmith/bestax/badge)](https://scorecard.dev/viewer/?uri=github.com/allxsmith/bestax)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/14361/badge)](https://www.bestpractices.dev/projects/14361)\n[![npm provenance](https://img.shields.io/badge/npm-provenance-3fb950.svg)](https://www.npmjs.com/package/bestax-migrate#provenance)\n[![Security policy](https://img.shields.io/badge/security-policy-blue.svg)](https://github.com/allxsmith/bestax/blob/main/SECURITY.md)\n\nCodemods that migrate existing React apps to [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) — the actively maintained React component library for **Bulma v1**.\n\nCurrently supported sources:\n\n| Source | Status |\n| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |\n| [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |\n| [`rbx`](https://github.com/dfee/rbx) (v2) | ✅ Full export surface mapped (a few patterns are flagged as TODOs) |\n| [`bloomer`](https://github.com/AlgusDark/bloomer) (0.6) | ✅ All 108 exports mapped (Font Awesome 4 icons and Bulma 0.4's `Nav` are flagged) |\n| `bulma-classes`: Bulma's classes on plain JSX, no library | ✅ Converts an element only when bestax renders the same markup; the rest is flagged |\n| `bulma-classes` on HTML: static pages and templates styled with Bulma | ✅ Writes a React component beside each page; its head and scripts are flagged |\n\nPass the source as the first argument: `bestax-migrate <source> <paths…>`.\n\n## Requirements\n\n**Node.js 22 or newer.** Node 18 and 20 are both past end-of-life. On an older runtime the CLI\nexits immediately with an explicit upgrade message.\n\nThis applies only to the Node version the codemod itself runs on. It places no requirement on\nthe app being migrated — the source is read as text and is never executed.\n\n## Usage\n\n```bash\n# Preview what would change (no writes)\npnpm dlx bestax-migrate react-bulma-components src/ --dry\n# …or, for an rbx or bloomer app\npnpm dlx bestax-migrate rbx src/ --dry\npnpm dlx bestax-migrate bloomer src/ --dry\n# …or, for an app that writes Bulma's classes on plain JSX\npnpm dlx bestax-migrate bulma-classes src/ --dry\n# …or, for static HTML pages styled with Bulma: name a page, or walk a folder with -e html\n# (-e html,htm takes .htm pages too)\npnpm dlx bestax-migrate bulma-classes src/pages/login/index.html --dry\npnpm dlx bestax-migrate bulma-classes -e html src/pages/ --dry\n\n# Apply the migration\npnpm dlx bestax-migrate react-bulma-components src/\n```\n\nnpm and yarn work too: `npx bestax-migrate …` / `yarn dlx bestax-migrate …`.\n\nThe codemod uses [jscodeshift](https://github.com/facebook/jscodeshift) to:\n\n- rewrite the source library's imports to `@allxsmith/bestax-bulma` (including destructuring and namespace imports)\n- 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`)\n- convert props (`renderAs` → `as`, `loading` → `isLoading`, numeric spacing/text sizes → string unions, `textAlign=\"center\"` → `textAlign=\"centered\"`, …)\n- flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`) and bloomer's `isDisplay`/`isHidden` strings, arrays and objects (`isHidden=\"touch\"` → `visibilityTouch=\"hidden\"`)\n- for `bulma-classes`, turn raw Bulma markup into components and props (`<a className=\"button is-primary\">` → `<Button as=\"a\" color=\"primary\">`, `<p className=\"has-text-centered mt-4\">` → `<Paragraph textAlign=\"centered\" mt=\"4\">`), converting an element only when bestax renders exactly the same markup\n- for `bulma-classes` on an HTML page, write a React module beside it (`index.html` → `index.tsx`, or `.jsx` when the package isn't TypeScript) whose default export is the page's body as a component (`LoginPage`), converted as the same markup written as JSX would be. The page is never changed and an existing module is never overwritten; the head, the `<html>` and `<body>` attributes, the stylesheets and scripts it loads, and inline handlers are left as `html-*` TODOs, except that under `--css bestax` or `--css bulma` the module imports the stylesheet in place of the page's Bulma `<link>`\n- restructure patterns bestax models differently (`Table.Container`, Navbar dropdowns, `Form.Help`, icon-font children → `<Icon name=…>`)\n- 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'`\n- 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. For **bulma-classes** there is no library to remove, and by default (`--css keep`) the app's Bulma version, Sass and stylesheet imports all stay: its own Bulma already styles every class a converted element renders. `--css bestax` or `--css bulma` moves it to Bulma v1 like the other sources\n\nAnything 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), [Bulma classes](https://bestax.io/docs/guides/getting-started/migration/bulma-classes)), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:\n\n```bash\nnpx skills add https://github.com/allxsmith/bestax --skill bestax-migrate\n```\n\n### Through the Codemod Registry\n\nbestax-migrate is also in the [Codemod Registry](https://app.codemod.com/registry) as `bestax-migrate`, for teams that run their migrations through Codemod. That package runs this CLI from npm at a pinned release, which can trail the newest one:\n\n```bash\n# Preview (no writes)\nnpx codemod bestax-migrate --workflow preview --param source=react-bulma-components\n# Apply\nnpx codemod bestax-migrate --param source=react-bulma-components\n```\n\nRun it from your app root. `--param paths=\"src lib\"` (default `src`) and `--param options=\"--css keep\"` pass through to the CLI. Codemod's own `--dry-run` skips the shell step this package runs, so use the `preview` workflow for a dry run.\n\n## Options\n\n| Flag | Description |\n| -------------------- | ---------------------------------------------------------------------------------------------- |\n| `--dry`, `-d` | Report what would change without writing files |\n| `--print`, `-p` | Print transformed sources to stdout, still writing them unless `--dry` is set |\n| `--extensions`, `-e` | File extensions to include in a folder (default `js,jsx,ts,tsx,scss,sass`; `html` for pages) |\n| `--css <mode>` | Stylesheet target: `bestax`, `bulma`, or `keep` (default `bestax`; `keep` for `bulma-classes`) |\n| `--no-deps` | Skip updating package.json dependencies |\n\n## After the codemod\n\n1. Run your package manager's install (the codemod rewrote `package.json` but never installs)\n2. Search for `TODO(bestax-migrate)` and resolve each comment\n3. Typecheck/build and review the rendered app\n\nFull 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) · [Bulma classes migration guide](https://bestax.io/docs/guides/getting-started/migration/bulma-classes).\n\n## Hardened by default\n\nA codemod rewrites your source in place, so how it is built and published matters:\n\n- **Signed provenance** — every release carries a sigstore attestation linking the tarball to the exact commit and CI run that built it. Check the **Provenance** section on the [npm page](https://www.npmjs.com/package/bestax-migrate#provenance), or run `npm audit signatures`.\n- **npm OIDC trusted publishing** — short-lived, per-run credentials; no long-lived `NPM_TOKEN` exists to be stolen. Release commits and tags are GPG-signed.\n- **Socket.dev scans every PR** for malware, install scripts, obfuscated code, and privilege escalation before it can reach `main`.\n- **The libraries this tool migrates away from are never installed here** — source fixtures are read as text only, so no unmaintained third-party package enters the dependency tree.\n- **Dependencies are a deliberate act** — install scripts are blocked unless individually allow-listed, freshly published versions are refused for 3 days, and CI installs only what the reviewed lockfile resolves.\n- **Every GitHub Action is pinned to a full commit SHA**, and CodeQL, Dependency Review, and Dependabot run continuously alongside a high-severity `pnpm audit` gate.\n- **Layered AI review before merge** — [CodeRabbit](https://coderabbit.ai) plus an independent adversarial Claude review (a different model from the one writing AI-authored changes), on top of required green CI, an approving review, and a human merge.\n\nFull detail: [`SECURITY.md`](https://github.com/allxsmith/bestax/blob/main/SECURITY.md) · [Security guide](https://bestax.io/docs/guides/security)\n\n## Telemetry\n\n`bestax-migrate` can send one **anonymous** usage event after a successful\nrun — only if you opt in when asked (once, on an interactive terminal). The\nevent is just the run's shape — source library, CSS mode, the dry/deps flags, a\ncapped changed-file count, and per-rule TODO counts — plus the CLI version,\nNode major version, and OS platform name. Never file paths, file contents,\ncode, names, IPs, or machine IDs, and no identifier exists that could link two\nevents together. Opt out any time with `--no-telemetry`,\n`BESTAX_TELEMETRY=0`, or `DO_NOT_TRACK=1`.\n\nFull disclosure of every field and control: [Telemetry guide](https://bestax.io/docs/guides/telemetry)\n\n## License\n\nSource code licensed MIT\n"
82
82
  }