bestax-migrate 2.3.7 → 2.3.9
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 +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -6
- package/dist/sources/_shared/bestax-import.d.ts +45 -0
- package/dist/sources/_shared/bestax-import.d.ts.map +1 -0
- package/dist/sources/_shared/bestax-import.js +141 -0
- package/dist/sources/_shared/css-imports.d.ts +33 -0
- package/dist/sources/_shared/css-imports.d.ts.map +1 -0
- package/dist/sources/_shared/css-imports.js +103 -0
- package/dist/sources/_shared/deps-common.d.ts +46 -0
- package/dist/sources/_shared/deps-common.d.ts.map +1 -0
- package/dist/sources/_shared/deps-common.js +98 -0
- package/dist/sources/_shared/make-styles-transform.d.ts +6 -2
- package/dist/sources/_shared/make-styles-transform.d.ts.map +1 -1
- package/dist/sources/_shared/make-styles-transform.js +12 -4
- package/dist/sources/_shared/specials-utils.d.ts +1 -1
- package/dist/sources/_shared/specials-utils.d.ts.map +1 -1
- package/dist/sources/_shared/specials-utils.js +19 -1
- package/dist/sources/bloomer/deps.d.ts.map +1 -1
- package/dist/sources/bloomer/deps.js +14 -89
- package/dist/sources/bloomer/transform.d.ts.map +1 -1
- package/dist/sources/bloomer/transform.js +9 -185
- package/dist/sources/rbx/deps.d.ts.map +1 -1
- package/dist/sources/rbx/deps.js +29 -117
- package/dist/sources/rbx/mapping.d.ts.map +1 -1
- package/dist/sources/rbx/mapping.js +9 -1
- package/dist/sources/rbx/specials.d.ts.map +1 -1
- package/dist/sources/rbx/specials.js +20 -10
- package/dist/sources/rbx/transform.d.ts.map +1 -1
- package/dist/sources/rbx/transform.js +19 -203
- package/dist/sources/react-bulma-components/deps.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/deps.js +12 -87
- package/dist/sources/react-bulma-components/mapping.js +1 -1
- package/dist/sources/react-bulma-components/specials.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/specials.js +42 -4
- package/dist/sources/react-bulma-components/transform.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/transform.js +13 -186
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -78,6 +78,14 @@ export const UNIVERSAL_PROPS = {
|
|
|
78
78
|
relative: {}, // boolean on both sides
|
|
79
79
|
// Per-component maps override this with AS_OK where bestax has an `as`.
|
|
80
80
|
as: AS_TODO,
|
|
81
|
+
// Same shape: the per-component maps override this with `rename: 'ref'` on
|
|
82
|
+
// the targets that forward one, and the `navbar-item` special handles the
|
|
83
|
+
// two it chooses between. Whatever is left reaches here, so no `innerRef`
|
|
84
|
+
// migrates in silence onto a target that cannot take it — the RBC sibling
|
|
85
|
+
// `domRef` has been flagged universally all along.
|
|
86
|
+
innerRef: {
|
|
87
|
+
todo: `\`innerRef\` has no counterpart; rename it to \`ref\` if this target forwards one, otherwise move it onto a wrapping element you control (${DOCS}/api)`,
|
|
88
|
+
},
|
|
81
89
|
};
|
|
82
90
|
/** rbx badge helper props → bestax `<Badge>` props. */
|
|
83
91
|
export const BADGE_PROPS = {
|
|
@@ -121,7 +129,7 @@ export const MAPPING = {
|
|
|
121
129
|
},
|
|
122
130
|
forwardRefAs: {
|
|
123
131
|
status: 'todo',
|
|
124
|
-
todo: '`forwardRefAs` is rbx-internal and has no counterpart. bestax forwards a ref from the form controls
|
|
132
|
+
todo: '`forwardRefAs` is rbx-internal and has no counterpart. bestax forwards a ref from the form controls, plus `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `Sidebar` and `Toast` — pass `ref` directly on those, though not on the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers, which forward none. Mind the `Navbar.Dropdown` collision: your rbx `Navbar.Dropdown` is the menu and becomes `Navbar.DropdownMenu`, which forwards no ref, while bestax `Navbar.Dropdown` — the container your `<Navbar.Item dropdown>` becomes — does. The rest, `Box` included, forward no ref: React 18 drops it with a warning, React 19 leaves it wherever the rest props go, so put the ref on a wrapping element you control',
|
|
125
133
|
},
|
|
126
134
|
// ---- elements -----------------------------------------------------------
|
|
127
135
|
Block: { status: 'mapped', target: 'Block' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAUL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAUL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AAq3B9B,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf"}
|
|
@@ -17,7 +17,7 @@ import { BADGE_PROPS, RESPONSIVE_BREAKPOINTS, TOOLTIP_PROPS, UNIVERSAL_PROPS, }
|
|
|
17
17
|
import { addAttr, addTodo, buildJsxName, attributesOf, findAttr, jsxNameParts, literalValueOf, makeAttr, plainElement, removeAttr, resolveBooleanish, } from '../_shared/jsx-utils.js';
|
|
18
18
|
import { alignTarget, applyIconProps, makeStripModifierProps, makeStructuralHelpers, mergeClassName, modifierClass, parseIconClasses, restrictAsToTargets, } from '../_shared/specials-utils.js';
|
|
19
19
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
20
|
-
const stripModifierProps = makeStripModifierProps(UNIVERSAL_PROPS, RESPONSIVE_BREAKPOINTS);
|
|
20
|
+
const stripModifierProps = makeStripModifierProps(UNIVERSAL_PROPS, RESPONSIVE_BREAKPOINTS, 'innerRef');
|
|
21
21
|
/**
|
|
22
22
|
* Also strips the universal `responsive` object: responsive.ts would have
|
|
23
23
|
* consumed it, but a `replaced: true` special skips that pass too, and it is
|
|
@@ -513,17 +513,27 @@ const SPECIALS = {
|
|
|
513
513
|
// bestax's `Navbar.Dropdown` forwards a ref, but it is the one such target
|
|
514
514
|
// the `innerRef: { rename: 'ref' }` entries in mapping.ts cannot reach:
|
|
515
515
|
// that table is keyed on the rbx name (`Navbar.Item`), and only this
|
|
516
|
-
// handler knows which of the two targets was picked.
|
|
517
|
-
//
|
|
518
|
-
//
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
516
|
+
// handler knows which of the two targets was picked. The condition is
|
|
517
|
+
// about that, not about ref support: a plain `Navbar.Item` forwards one
|
|
518
|
+
// too since #661, so leaving `innerRef` alone there is a rename this
|
|
519
|
+
// handler declines rather than one the target cannot take. Performing it
|
|
520
|
+
// changes emitted output on code that migrates today, so it stays #734 —
|
|
521
|
+
// but declining silently is not an option either. `innerRef` is in no
|
|
522
|
+
// rbx prop table, so nothing downstream flags it and it used to reach the
|
|
523
|
+
// DOM as an unknown attribute with the report saying nothing, which is
|
|
524
|
+
// the silent skip bestax-migrate/CLAUDE.md rules out. It is flagged here
|
|
525
|
+
// instead, and the rename stays the user's to make.
|
|
526
|
+
const handledInnerRef = [];
|
|
527
|
+
const innerRefAttr = findAttr(element, 'innerRef');
|
|
528
|
+
if (innerRefAttr) {
|
|
529
|
+
handledInnerRef.push('innerRef');
|
|
530
|
+
if (target === 'Navbar.Dropdown') {
|
|
523
531
|
innerRefAttr.name = ctx.j.jsxIdentifier('ref');
|
|
524
|
-
renamedInnerRef.push('innerRef');
|
|
525
532
|
ctx.dirty = true;
|
|
526
533
|
}
|
|
534
|
+
else {
|
|
535
|
+
addTodo(ctx, path, 'prop:innerRef', 'bestax `Navbar.Item` forwards a ref; rename `innerRef` to `ref` by hand');
|
|
536
|
+
}
|
|
527
537
|
}
|
|
528
538
|
restrictAsToTargets(ctx, path, element, target ?? 'Navbar.Item', [
|
|
529
539
|
'Navbar.Item',
|
|
@@ -538,7 +548,7 @@ const SPECIALS = {
|
|
|
538
548
|
'expanded',
|
|
539
549
|
'hoverable',
|
|
540
550
|
'managed',
|
|
541
|
-
...
|
|
551
|
+
...handledInnerRef,
|
|
542
552
|
],
|
|
543
553
|
};
|
|
544
554
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAiDvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA07BpB"}
|
|
@@ -23,29 +23,13 @@ import { BADGE_PROPS, MAPPING, TOOLTIP_PROPS, UNIVERSAL_PROPS, resolveMapping, }
|
|
|
23
23
|
import { addTodo, attributesOf, findAttr, jsxNameParts, literalValueOf, removeAttr, renameElement, } from '../_shared/jsx-utils.js';
|
|
24
24
|
import { applyPropAction, applyUniversalProps } from '../_shared/props.js';
|
|
25
25
|
import { enforcePolymorphicProps } from '../_shared/polymorphic.js';
|
|
26
|
+
import { bestaxValueLocals, buildBestaxImport, carryPrunedComments, placeBestaxImport, seedBestaxImport, } from '../_shared/bestax-import.js';
|
|
27
|
+
import { rewriteStylesheetImports } from '../_shared/css-imports.js';
|
|
26
28
|
import { collectBoundNames, makeAliasRegistry, makeReserve, nameOf, prefersTabs, resolvesToBinding, } from '../_shared/imports.js';
|
|
27
29
|
import { flattenResponsiveProps, RESPONSIVE_KINDS } from './responsive.js';
|
|
28
30
|
import { runSpecial } from './specials.js';
|
|
29
31
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
30
32
|
const RBX = 'rbx';
|
|
31
|
-
const BESTAX = '@allxsmith/bestax-bulma';
|
|
32
|
-
const BULMA_CSS = 'bulma/css/bulma.min.css';
|
|
33
|
-
const BESTAX_CSS = '@allxsmith/bestax-bulma/bestax.css';
|
|
34
|
-
const EXTRAS_CSS = '@allxsmith/bestax-bulma/extras.css';
|
|
35
|
-
const BULMA_CSS_SPECIFIERS = new Set([
|
|
36
|
-
'bulma/css/bulma.css',
|
|
37
|
-
'bulma/css/bulma.min.css',
|
|
38
|
-
]);
|
|
39
|
-
const BESTAX_CSS_SPECIFIERS = new Set([
|
|
40
|
-
BESTAX_CSS,
|
|
41
|
-
'@allxsmith/bestax-bulma/bestax.min.css',
|
|
42
|
-
'@allxsmith/bestax-bulma/dist/bestax.css',
|
|
43
|
-
'@allxsmith/bestax-bulma/dist/bestax.min.css',
|
|
44
|
-
]);
|
|
45
|
-
const EXTRAS_CSS_SPECIFIERS = new Set([
|
|
46
|
-
EXTRAS_CSS,
|
|
47
|
-
'@allxsmith/bestax-bulma/dist/extras.css',
|
|
48
|
-
]);
|
|
49
33
|
/**
|
|
50
34
|
* The four Bulma extensions rbx pinned. An app that imported their CSS
|
|
51
35
|
* directly no longer needs to: bestax ships Badge/Tooltip/Loading/Divider.
|
|
@@ -125,35 +109,17 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
125
109
|
addTodo(ctx, p, 'imports', `\`export * from '${RBX}'\` was not migrated; re-export the bestax components you need by hand`);
|
|
126
110
|
});
|
|
127
111
|
// ---- 1a. Stylesheet imports (mode-driven) -----------------------------
|
|
128
|
-
// `
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
.paths()
|
|
135
|
-
.some(p => BESTAX_CSS_SPECIFIERS.has(String(p.node.source.value)));
|
|
136
|
-
// Whether some import in this file will become bestax.css, regardless of
|
|
137
|
-
// where it sits relative to an existing extras import.
|
|
138
|
-
const willAdoptBestaxCss = cssMode === 'bestax' &&
|
|
139
|
-
root
|
|
140
|
-
.find(j.ImportDeclaration)
|
|
141
|
-
.paths()
|
|
142
|
-
.some(p => {
|
|
143
|
-
const v = String(p.node.source.value);
|
|
144
|
-
return ((v.startsWith(`${RBX}/`) && v.endsWith('.css')) ||
|
|
145
|
-
BULMA_CSS_SPECIFIERS.has(v));
|
|
146
|
-
});
|
|
147
|
-
root.find(j.ImportDeclaration).forEach(path => {
|
|
148
|
-
const source = String(path.node.source.value);
|
|
149
|
-
const isRbxCss = source.startsWith(`${RBX}/`) && source.endsWith('.css');
|
|
150
|
-
const isBulmaCss = BULMA_CSS_SPECIFIERS.has(source);
|
|
151
|
-
const isExtrasCss = EXTRAS_CSS_SPECIFIERS.has(source);
|
|
112
|
+
// `keep` retargets only the dead rbx CSS import, which carries Bulma 0.7.5.
|
|
113
|
+
rewriteStylesheetImports(ctx, root, options.cssMode ?? 'bestax', {
|
|
114
|
+
sourceCss: {
|
|
115
|
+
is: specifier => specifier.startsWith(`${RBX}/`) && specifier.endsWith('.css'),
|
|
116
|
+
label: "rbx's CSS import",
|
|
117
|
+
},
|
|
152
118
|
// The four extensions rbx pinned; bestax covers all of them.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
119
|
+
handleOwn: (path, source) => {
|
|
120
|
+
if (!RBX_EXTENSION_CSS.test(source) || !source.endsWith('.css')) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
157
123
|
// Kept, with a TODO, rather than dropped. The rbx JSX that needed this
|
|
158
124
|
// stylesheet becomes bestax components that carry their own styles, so
|
|
159
125
|
// for THAT markup it is dead -- but an app can also use the extension's
|
|
@@ -164,50 +130,8 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
164
130
|
// manifest pass, which reports the same extensions rather than removing
|
|
165
131
|
// them for exactly this reason.
|
|
166
132
|
addTodo(ctx, path, 'css', `kept \`${source}\`: bestax ships Badge, Tooltip, Loading and Divider with their own styles, so this is only still needed by markup outside rbx that uses the extension's classes directly — drop the import once nothing does`);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (cssMode === 'bestax') {
|
|
170
|
-
if (isRbxCss || isBulmaCss) {
|
|
171
|
-
if (sawBestaxCss) {
|
|
172
|
-
path.prune(); // bestax.css already imported elsewhere in this file
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
path.node.source = j.stringLiteral(BESTAX_CSS);
|
|
176
|
-
sawBestaxCss = true;
|
|
177
|
-
}
|
|
178
|
-
ctx.dirty = true;
|
|
179
|
-
}
|
|
180
|
-
else if (isExtrasCss && (sawBestaxCss || willAdoptBestaxCss)) {
|
|
181
|
-
// bestax.css already contains the extras. `willAdoptBestaxCss` covers
|
|
182
|
-
// the case where the extras import comes FIRST in the file and the
|
|
183
|
-
// bulma/rbx import that becomes bestax.css has not been visited yet —
|
|
184
|
-
// previously the extras survived alongside it and double-loaded.
|
|
185
|
-
path.prune();
|
|
186
|
-
ctx.dirty = true;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
else if (cssMode === 'bulma') {
|
|
190
|
-
if (isRbxCss) {
|
|
191
|
-
path.node.source = j.stringLiteral(BULMA_CSS);
|
|
192
|
-
ctx.dirty = true;
|
|
193
|
-
}
|
|
194
|
-
if ((isRbxCss || isBulmaCss) && !sawBestaxCss) {
|
|
195
|
-
const hasExtras = root
|
|
196
|
-
.find(j.ImportDeclaration)
|
|
197
|
-
.paths()
|
|
198
|
-
.some(p => EXTRAS_CSS_SPECIFIERS.has(String(p.node.source.value)));
|
|
199
|
-
if (!hasExtras) {
|
|
200
|
-
// Themed Radio/Checkbox need the bestax extras next to plain Bulma.
|
|
201
|
-
path.insertAfter(j.importDeclaration([], j.stringLiteral(EXTRAS_CSS)));
|
|
202
|
-
ctx.dirty = true;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
else if (isRbxCss) {
|
|
207
|
-
// keep: minimal fix — rbx's CSS carries Bulma 0.7.5.
|
|
208
|
-
path.node.source = j.stringLiteral(BULMA_CSS);
|
|
209
|
-
addTodo(ctx, path, 'css', `replaced rbx's CSS import with '${BULMA_CSS}'; install bulma@^1 (see https://bestax.io/docs/guides/getting-started/installation)`);
|
|
210
|
-
}
|
|
133
|
+
return true;
|
|
134
|
+
},
|
|
211
135
|
});
|
|
212
136
|
if (imports.size === 0 && !ctx.dirty) {
|
|
213
137
|
return undefined;
|
|
@@ -392,45 +316,7 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
392
316
|
bound.add(head);
|
|
393
317
|
});
|
|
394
318
|
ctx.reserve = makeReserve(ctx, bound);
|
|
395
|
-
|
|
396
|
-
// existing bestax import's specifiers below (so JSX reuses their locals),
|
|
397
|
-
// and that seeding alone must not turn a type-only specifier into a value
|
|
398
|
-
// import nobody needed.
|
|
399
|
-
const requested = new Set();
|
|
400
|
-
const baseReserve = ctx.reserve;
|
|
401
|
-
ctx.reserve = root => {
|
|
402
|
-
requested.add(root);
|
|
403
|
-
return baseReserve(root);
|
|
404
|
-
};
|
|
405
|
-
// Merge with an existing bestax import: reuse its locals verbatim.
|
|
406
|
-
// Only a declaration that already uses NAMED specifiers can absorb more of
|
|
407
|
-
// them. `import * as Bestax from '…'` cannot: a namespace specifier may not
|
|
408
|
-
// share a declaration with named ones, and appending to it emits a file
|
|
409
|
-
// that does not parse.
|
|
410
|
-
const existingBestax = root
|
|
411
|
-
.find(j.ImportDeclaration, { source: { value: BESTAX } })
|
|
412
|
-
.paths()
|
|
413
|
-
.find(p =>
|
|
414
|
-
// A type-only declaration cannot take a value specifier: merging a
|
|
415
|
-
// component into `import type { … }` erases it at runtime.
|
|
416
|
-
p.node.importKind !== 'type' &&
|
|
417
|
-
(p.node.specifiers ?? []).every((spec) => spec.type === 'ImportSpecifier'));
|
|
418
|
-
const preExistingImports = new Set();
|
|
419
|
-
if (existingBestax) {
|
|
420
|
-
for (const spec of existingBestax.node.specifiers ?? []) {
|
|
421
|
-
if (spec.type === 'ImportSpecifier' && spec.local) {
|
|
422
|
-
// The local name is reused either way, so the JSX never needs an
|
|
423
|
-
// alias. But an inline `type` specifier (`import { type Box }`) is
|
|
424
|
-
// not a value binding: it is not counted as already imported, so the
|
|
425
|
-
// component is written as a value below — onto this specifier, which
|
|
426
|
-
// keeps its name, rather than as a duplicate.
|
|
427
|
-
ctx.needed.set(nameOf(spec.imported), nameOf(spec.local));
|
|
428
|
-
if (spec.importKind !== 'type') {
|
|
429
|
-
preExistingImports.add(nameOf(spec.imported));
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
319
|
+
const bestaxImportState = seedBestaxImport(ctx, root);
|
|
434
320
|
/**
|
|
435
321
|
* Move one family of rbx helper props onto a wrapping bestax component.
|
|
436
322
|
* Returns the wrapper element, or null when the element carries none of
|
|
@@ -871,62 +757,13 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
871
757
|
// ---- 3. Rewrite imports -----------------------------------------------
|
|
872
758
|
if (imports.size > 0) {
|
|
873
759
|
const retainedNames = [...ctx.retained].sort((a, b) => a.localeCompare(b));
|
|
874
|
-
const
|
|
875
|
-
.filter(([imported]) => requested.has(imported) && !preExistingImports.has(imported))
|
|
876
|
-
.sort((a, b) => a[0].localeCompare(b[0]));
|
|
877
|
-
const bestaxImport = freshNames.length > 0
|
|
878
|
-
? j.importDeclaration(freshNames.map(([imported, local]) => j.importSpecifier(j.identifier(imported), j.identifier(local))), j.stringLiteral(BESTAX))
|
|
879
|
-
: null;
|
|
880
|
-
/**
|
|
881
|
-
|
|
882
|
-
* A pruned declaration takes its comments with it — a licence header, an
|
|
883
|
-
|
|
884
|
-
* eslint directive. Hand them to what replaces it, or to the next statement.
|
|
885
|
-
|
|
886
|
-
*/
|
|
887
|
-
const carryComments = (node, importPath) => {
|
|
888
|
-
const comments = node.comments ?? [];
|
|
889
|
-
if (comments.length === 0)
|
|
890
|
-
return;
|
|
891
|
-
const body = importPath.parent?.node?.body ?? [];
|
|
892
|
-
const index = body.indexOf(node);
|
|
893
|
-
// The fresh specifiers are merged INTO an existing bestax import when there
|
|
894
|
-
// is one, and the `bestaxImport` node is then discarded — so the comments
|
|
895
|
-
// have to follow the declaration that survives, not the one that does not.
|
|
896
|
-
const carrier = (existingBestax ? existingBestax.node : bestaxImport) ??
|
|
897
|
-
(index >= 0 ? body[index + 1] : undefined);
|
|
898
|
-
if (carrier) {
|
|
899
|
-
carrier.comments = [...comments, ...(carrier.comments ?? [])];
|
|
900
|
-
}
|
|
901
|
-
else if (index > 0) {
|
|
902
|
-
// The import was the last statement: the comments stay where they
|
|
903
|
-
// were, after what precedes it.
|
|
904
|
-
const previous = body[index - 1];
|
|
905
|
-
previous.comments = [
|
|
906
|
-
...(previous.comments ?? []),
|
|
907
|
-
...comments.map((c) => ({
|
|
908
|
-
...c,
|
|
909
|
-
leading: false,
|
|
910
|
-
trailing: true,
|
|
911
|
-
})),
|
|
912
|
-
];
|
|
913
|
-
}
|
|
914
|
-
else {
|
|
915
|
-
// The import was the only statement: the comments become the file's.
|
|
916
|
-
const program = importPath.parent?.node;
|
|
917
|
-
if (program)
|
|
918
|
-
program.comments = [...comments, ...(program.comments ?? [])];
|
|
919
|
-
}
|
|
920
|
-
node.comments = [];
|
|
921
|
-
};
|
|
760
|
+
const bestaxImport = buildBestaxImport(ctx, bestaxImportState);
|
|
922
761
|
let inserted = false;
|
|
923
762
|
// A retained rbx specifier must never collide with a bestax import local
|
|
924
763
|
// (possible when one component is both JSX-migrated and value-retained).
|
|
925
764
|
// Only a VALUE local can collide at runtime: a type-only specifier the
|
|
926
765
|
// seeding above recorded, and nothing promoted, binds no value.
|
|
927
|
-
const bestaxLocals =
|
|
928
|
-
.filter(([imported]) => requested.has(imported) || preExistingImports.has(imported))
|
|
929
|
-
.map(([, local]) => local));
|
|
766
|
+
const bestaxLocals = bestaxValueLocals(ctx, bestaxImportState);
|
|
930
767
|
for (const path of rbxImportPaths) {
|
|
931
768
|
const node = path.node;
|
|
932
769
|
const keepSpecifiers = (node.specifiers ?? []).filter((spec) => {
|
|
@@ -944,28 +781,7 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
944
781
|
!bestaxLocals.has(nameOf(spec.local)));
|
|
945
782
|
});
|
|
946
783
|
if (!inserted) {
|
|
947
|
-
|
|
948
|
-
const current = existingBestax.node.specifiers ?? [];
|
|
949
|
-
const appended = [];
|
|
950
|
-
for (const fresh of bestaxImport.specifiers) {
|
|
951
|
-
// A type-only specifier for the same name becomes the value
|
|
952
|
-
// import (a value import carries the type too); appending a
|
|
953
|
-
// second `Box` beside `type Box` would be a duplicate identifier.
|
|
954
|
-
const typeOnly = current.find((spec) => spec.type === 'ImportSpecifier' &&
|
|
955
|
-
spec.importKind === 'type' &&
|
|
956
|
-
nameOf(spec.imported) === nameOf(fresh.imported));
|
|
957
|
-
if (typeOnly) {
|
|
958
|
-
typeOnly.importKind = null;
|
|
959
|
-
}
|
|
960
|
-
else {
|
|
961
|
-
appended.push(fresh);
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
existingBestax.node.specifiers = [...current, ...appended];
|
|
965
|
-
}
|
|
966
|
-
else if (bestaxImport) {
|
|
967
|
-
path.insertBefore(bestaxImport);
|
|
968
|
-
}
|
|
784
|
+
placeBestaxImport(bestaxImportState, bestaxImport, path);
|
|
969
785
|
inserted = true;
|
|
970
786
|
}
|
|
971
787
|
const droppedOnCollision = (node.specifiers ?? []).filter((spec) => spec.type === 'ImportSpecifier' &&
|
|
@@ -988,7 +804,7 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
988
804
|
}
|
|
989
805
|
}
|
|
990
806
|
else {
|
|
991
|
-
|
|
807
|
+
carryPrunedComments(node, path, bestaxImportState.existing?.node ?? bestaxImport);
|
|
992
808
|
path.prune();
|
|
993
809
|
}
|
|
994
810
|
ctx.dirty = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAUzD,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAUzD,eAAO,MAAM,kBAAkB,EAAE,kBAuChC,CAAC"}
|
|
@@ -4,28 +4,17 @@
|
|
|
4
4
|
* with dart-sass. Pure data-in/data-out — the CLI owns file IO, and no
|
|
5
5
|
* package manager is ever invoked (the report tells the user to install).
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
const BESTAX_RANGE = '^5';
|
|
9
|
-
const BULMA_RANGE = '^1.0.4';
|
|
10
|
-
// Bulma v1's sass tree uses `color.channel(…)` — needs dart-sass ≥ 1.79.
|
|
11
|
-
const SASS_RANGE = '^1.79.0';
|
|
12
|
-
const DEP_SECTIONS = ['dependencies', 'devDependencies'];
|
|
7
|
+
import { DEP_SECTIONS, addBestax, moveBulmaToV1, openManifest, replaceNodeSass, reportPeerRanges, } from '../_shared/deps-common.js';
|
|
13
8
|
export const updateDependencies = (filePath, pkg, collector, options) => {
|
|
14
|
-
const
|
|
15
|
-
const next = pkg;
|
|
16
|
-
const section = (name) => (next[name] ?? undefined);
|
|
17
|
-
const note = (message) => {
|
|
18
|
-
changes.push(message);
|
|
19
|
-
collector?.add({ file: filePath, line: null, rule: 'deps', message });
|
|
20
|
-
};
|
|
9
|
+
const manifest = openManifest(filePath, pkg, collector);
|
|
21
10
|
// react-bulma-components goes away entirely.
|
|
22
11
|
let removedSource = false;
|
|
23
12
|
for (const name of DEP_SECTIONS) {
|
|
24
|
-
const deps = section(name);
|
|
13
|
+
const deps = manifest.section(name);
|
|
25
14
|
if (deps && 'react-bulma-components' in deps) {
|
|
26
15
|
delete deps['react-bulma-components'];
|
|
27
16
|
removedSource = true;
|
|
28
|
-
note(`removed react-bulma-components from ${name}`);
|
|
17
|
+
manifest.note(`removed react-bulma-components from ${name}`);
|
|
29
18
|
}
|
|
30
19
|
}
|
|
31
20
|
// The transform deliberately RETAINS imports for components with no bestax
|
|
@@ -35,76 +24,12 @@ export const updateDependencies = (filePath, pkg, collector, options) => {
|
|
|
35
24
|
// letting them find out at build time. rbx has carried this warning since
|
|
36
25
|
// it shipped; this source retains imports the same way and did not.
|
|
37
26
|
if (removedSource && options.sourceStillImported) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const dependencies = (next.dependencies ??= {});
|
|
47
|
-
if (!dependencies['@allxsmith/bestax-bulma'] &&
|
|
48
|
-
!section('devDependencies')?.['@allxsmith/bestax-bulma']) {
|
|
49
|
-
dependencies['@allxsmith/bestax-bulma'] = BESTAX_RANGE;
|
|
50
|
-
note(`added @allxsmith/bestax-bulma ${BESTAX_RANGE} to dependencies`);
|
|
51
|
-
}
|
|
52
|
-
// Bulma: bump a pre-1 range; add only when sources still reference bulma/…
|
|
53
|
-
// directly (otherwise it arrives transitively via bestax-bulma).
|
|
54
|
-
let bulmaDeclared = false;
|
|
55
|
-
for (const name of DEP_SECTIONS) {
|
|
56
|
-
const deps = section(name);
|
|
57
|
-
if (deps?.bulma) {
|
|
58
|
-
bulmaDeclared = true;
|
|
59
|
-
if (isPreV1(deps.bulma)) {
|
|
60
|
-
deps.bulma = BULMA_RANGE;
|
|
61
|
-
note(`bumped bulma to ${BULMA_RANGE} in ${name} (was pre-1.0)`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (!bulmaDeclared && options.bulmaReferenced) {
|
|
66
|
-
dependencies.bulma = BULMA_RANGE;
|
|
67
|
-
note(`added bulma ${BULMA_RANGE} to dependencies (sources import bulma/… directly)`);
|
|
68
|
-
}
|
|
69
|
-
// bestax-bulma requires React 18/19; RBC v4 also ran on 17. Report only —
|
|
70
|
-
// a React major upgrade is the app's own migration step.
|
|
71
|
-
for (const name of DEP_SECTIONS) {
|
|
72
|
-
const range = section(name)?.react;
|
|
73
|
-
if (range && /^[~^]?(?:[0-9]|1[0-7])(?:[.x]|$)/.test(range.trim())) {
|
|
74
|
-
collector?.add({
|
|
75
|
-
file: filePath,
|
|
76
|
-
line: null,
|
|
77
|
-
rule: 'peer-deps',
|
|
78
|
-
message: `react ${range} predates bestax-bulma's peer range (^18 || ^19) — upgrade react and react-dom to 18 or 19 before installing`,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// Font Awesome older than 6 conflicts with bestax-bulma's optional peer
|
|
83
|
-
// range and makes `npm install` fail with ERESOLVE. Report only — icon
|
|
84
|
-
// names change across FA majors, so upgrading is the app's decision.
|
|
85
|
-
for (const name of DEP_SECTIONS) {
|
|
86
|
-
const range = section(name)?.['@fortawesome/fontawesome-free'];
|
|
87
|
-
if (range && /^[~^]?[0-5](?:[.x]|$)/.test(range.trim())) {
|
|
88
|
-
collector?.add({
|
|
89
|
-
file: filePath,
|
|
90
|
-
line: null,
|
|
91
|
-
rule: 'peer-deps',
|
|
92
|
-
message: `@fortawesome/fontawesome-free ${range} predates bestax-bulma's optional peer range (^6.7.2 || ^7.0.0) — upgrade it, or install with \`npm install --legacy-peer-deps\``,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// node-sass is dead; dart-sass replaces it in the same section.
|
|
97
|
-
for (const name of DEP_SECTIONS) {
|
|
98
|
-
const deps = section(name);
|
|
99
|
-
if (deps && 'node-sass' in deps) {
|
|
100
|
-
delete deps['node-sass'];
|
|
101
|
-
note(`removed node-sass from ${name}`);
|
|
102
|
-
const sassDeclared = DEP_SECTIONS.some(s => section(s)?.sass);
|
|
103
|
-
if (!sassDeclared) {
|
|
104
|
-
deps.sass = SASS_RANGE;
|
|
105
|
-
note(`added sass ${SASS_RANGE} to ${name} (replaces node-sass)`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return changes.length > 0 ? next : null;
|
|
27
|
+
manifest.report('deps', 'react-bulma-components was removed from package.json, but some files still import it for components with no bestax equivalent — resolve those `TODO(bestax-migrate)` imports before installing, or re-add react-bulma-components until you have');
|
|
28
|
+
}
|
|
29
|
+
addBestax(manifest);
|
|
30
|
+
moveBulmaToV1(manifest, options.bulmaReferenced);
|
|
31
|
+
// RBC v4 also ran on React 17, which bestax-bulma's peer range excludes.
|
|
32
|
+
reportPeerRanges(manifest);
|
|
33
|
+
replaceNodeSass(manifest);
|
|
34
|
+
return manifest.result();
|
|
110
35
|
};
|
|
@@ -26,7 +26,7 @@ export const UNIVERSAL_PROPS = {
|
|
|
26
26
|
todo: 'this bestax component has no `as` prop; restructure the element instead',
|
|
27
27
|
},
|
|
28
28
|
domRef: {
|
|
29
|
-
todo: 'bestax-bulma has no `domRef`. The form controls
|
|
29
|
+
todo: 'bestax-bulma has no `domRef`. The form controls, plus `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `Sidebar` and `Toast` forward a ref — on those, rename `domRef` to `ref`, though not on the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers, which forward none. Mind the `Navbar.Dropdown` collision: the `Navbar.Item` that wrapped your dropdown became bestax `Navbar.Dropdown` and forwards one, while your `Navbar.Dropdown` became `Navbar.DropdownMenu` and does not. The rest forward no ref: React 18 drops it with a warning, React 19 leaves it wherever the rest props go, so put the ref on a DOM child or wrap the component',
|
|
30
30
|
},
|
|
31
31
|
// ColorProps
|
|
32
32
|
backgroundColor: { rename: 'bgColor' },
|
|
@@ -1 +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,EAWL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAQL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;
|
|
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,EAWL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAQL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AA82B9B,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"}
|
|
@@ -28,7 +28,7 @@ function keptAttrs(ctx, path, element, where, tag) {
|
|
|
28
28
|
const kept = new Set(stripModifierProps(ctx, path, attributesOf(element), where));
|
|
29
29
|
return (element.openingElement.attributes ?? []).filter((a) => a.type === 'JSXSpreadAttribute' || kept.has(a));
|
|
30
30
|
}
|
|
31
|
-
const stripModifierProps = makeStripModifierProps(UNIVERSAL_PROPS, RESPONSIVE_BREAKPOINTS);
|
|
31
|
+
const stripModifierProps = makeStripModifierProps(UNIVERSAL_PROPS, RESPONSIVE_BREAKPOINTS, 'domRef');
|
|
32
32
|
const SPECIALS = {
|
|
33
33
|
/**
|
|
34
34
|
* RBC defaults Columns `multiline` to TRUE (Bulma and bestax default to
|
|
@@ -490,7 +490,6 @@ const SPECIALS = {
|
|
|
490
490
|
removeAttr(element, activeAttr);
|
|
491
491
|
}
|
|
492
492
|
liClass = mergeClassName(ctx, path, element, liClass, 'Breadcrumb.Item');
|
|
493
|
-
const anchorAttrs = keptAttrs(ctx, path, element, 'Breadcrumb.Item', 'a');
|
|
494
493
|
const children = element.children ?? [];
|
|
495
494
|
const solidChildren = children.filter((c) => !(c.type === 'JSXText' && c.value.trim() === ''));
|
|
496
495
|
// `<Breadcrumb.Item><a href>…</a></Breadcrumb.Item>` already carries its
|
|
@@ -501,11 +500,37 @@ const SPECIALS = {
|
|
|
501
500
|
solidChildren[0].openingElement.name.name === 'a'
|
|
502
501
|
? solidChildren[0]
|
|
503
502
|
: null;
|
|
503
|
+
// The strip below renames `domRef` to `ref`, so a collision with a `ref`
|
|
504
|
+
// the anchor already sets is settled here, while the prop still carries
|
|
505
|
+
// the name the user wrote.
|
|
506
|
+
const domRefAttr = findAttr(element, 'domRef');
|
|
507
|
+
if (existingAnchor && domRefAttr && findAttr(existingAnchor, 'ref')) {
|
|
508
|
+
removeAttr(element, domRefAttr);
|
|
509
|
+
addTodo(ctx, path, 'prop:domRef', 'Breadcrumb.Item `domRef` was dropped: its <a> child already sets `ref` — reconcile by hand');
|
|
510
|
+
}
|
|
511
|
+
const anchorAttrs = keptAttrs(ctx, path, element, 'Breadcrumb.Item', 'a');
|
|
504
512
|
if (existingAnchor && anchorAttrs.length > 0) {
|
|
505
|
-
|
|
513
|
+
// Merging onto an anchor the user already wrote keeps the rule
|
|
514
|
+
// `collapseOntoChild` does: the item's spreads go FIRST, as one block in
|
|
515
|
+
// source order, so the anchor's explicit props still win over them; and
|
|
516
|
+
// a named prop both set keeps the anchor's value and is flagged, since
|
|
517
|
+
// writing it twice does not compile.
|
|
518
|
+
const spreads = anchorAttrs.filter((a) => a.type === 'JSXSpreadAttribute');
|
|
519
|
+
const merged = [
|
|
520
|
+
...spreads,
|
|
506
521
|
...(existingAnchor.openingElement.attributes ?? []),
|
|
507
|
-
...anchorAttrs,
|
|
508
522
|
];
|
|
523
|
+
for (const attr of anchorAttrs) {
|
|
524
|
+
if (attr.type === 'JSXSpreadAttribute')
|
|
525
|
+
continue;
|
|
526
|
+
const name = attr.name.name;
|
|
527
|
+
if (findAttr(existingAnchor, name)) {
|
|
528
|
+
addTodo(ctx, path, `prop:${name}`, `Breadcrumb.Item \`${name}\` was dropped: its <a> child already sets \`${name}\` — reconcile by hand`);
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
merged.push(attr);
|
|
532
|
+
}
|
|
533
|
+
existingAnchor.openingElement.attributes = merged;
|
|
509
534
|
}
|
|
510
535
|
const anchor = existingAnchor ?? plainElement(j, 'a', undefined, anchorAttrs, children);
|
|
511
536
|
path.replace(plainElement(j, 'li', liClass, [], [anchor]));
|
|
@@ -519,6 +544,19 @@ const SPECIALS = {
|
|
|
519
544
|
if (findAttr(element, 'className')) {
|
|
520
545
|
addTodo(ctx, path, 'prop:className', 'Table.Container className; the container folded into `isResponsive` on its Table — re-apply the class by hand');
|
|
521
546
|
}
|
|
547
|
+
// The container element is gone after the fold. What it carried
|
|
548
|
+
// (`domRef`, `id`, handlers) applied to the wrapping div, and moving it
|
|
549
|
+
// onto the Table would put it on the <table> instead, so it is reported
|
|
550
|
+
// rather than carried. Only `className` used to be reported.
|
|
551
|
+
for (const attr of attributesOf(element)) {
|
|
552
|
+
const name = attr?.name?.name;
|
|
553
|
+
if (!name || name === 'className')
|
|
554
|
+
continue;
|
|
555
|
+
addTodo(ctx, path, `prop:${name}`, `Table.Container \`${name}\` was dropped: the container folded into \`isResponsive\` on its Table, so there is no element left to carry it — re-apply by hand`);
|
|
556
|
+
}
|
|
557
|
+
if ((element.openingElement.attributes ?? []).some((a) => a.type === 'JSXSpreadAttribute')) {
|
|
558
|
+
addTodo(ctx, path, 'prop:spread', 'Table.Container spread props were dropped: the container folded into `isResponsive` on its Table, so there is no element left to carry them — re-apply by hand');
|
|
559
|
+
}
|
|
522
560
|
const child = children[0];
|
|
523
561
|
addAttr(child, makeAttr(ctx.j, 'isResponsive'));
|
|
524
562
|
path.replace(child);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkCvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA2wBpB"}
|