bestax-migrate 2.3.8 → 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/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 +2 -2
package/dist/cli.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { createInterface } from 'node:readline/promises';
|
|
|
15
15
|
import type { Readable, Writable } from 'node:stream';
|
|
16
16
|
import { Command } from 'commander';
|
|
17
17
|
import { type MigrateRunStats } from './telemetry.js';
|
|
18
|
+
import type { MigrationSource } from './types.js';
|
|
18
19
|
export declare function collectFiles(targets: string[], extensions: string[]): string[];
|
|
19
20
|
/** Nearest package.json for each target, walking up to the filesystem root. */
|
|
20
21
|
export declare function findPackageJsons(targets: string[]): string[];
|
|
@@ -75,6 +76,8 @@ export declare function blankComments(text: string): string;
|
|
|
75
76
|
* short as `rbx`: prose and a sibling package like `rbx-utils` both counted.
|
|
76
77
|
*/
|
|
77
78
|
export declare function makeSourceImportRe(name: string): RegExp;
|
|
79
|
+
/** The package a source migrates away from, or null when it has none. */
|
|
80
|
+
export declare function sourcePackage(source: MigrationSource): string | null;
|
|
78
81
|
/**
|
|
79
82
|
* One-question consent prompt (readline — this package carries no interactive
|
|
80
83
|
* prompt dependency). Returns null when the question is cancelled (Ctrl-C /
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;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;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;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,EAAW,eAAe,EAAE,MAAM,YAAY,CAAC;AAoB3D,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,GACnB,MAAM,EAAE,CAkBV;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;AAoKD;;;;;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,CAkHT"}
|
package/dist/cli.js
CHANGED
|
@@ -201,10 +201,19 @@ export function makeSourceImportRe(name) {
|
|
|
201
201
|
`${lead}(?:import|require(?:\\.resolve)?)\\s*\\(\\s*${spec}`,
|
|
202
202
|
].join('|'));
|
|
203
203
|
}
|
|
204
|
+
/** The package a source migrates away from, or null when it has none. */
|
|
205
|
+
export function sourcePackage(source) {
|
|
206
|
+
return source.packageName === undefined ? source.name : source.packageName;
|
|
207
|
+
}
|
|
208
|
+
/** Whether `text` still imports the source's package (never, without one). */
|
|
209
|
+
function importsSource(importRe, text) {
|
|
210
|
+
return importRe !== null && importRe.test(blankComments(text));
|
|
211
|
+
}
|
|
204
212
|
function migrateFiles(source, files, reporter, io, options) {
|
|
205
213
|
let bulmaReferenced = false;
|
|
206
214
|
let sourceStillImported = false;
|
|
207
|
-
const
|
|
215
|
+
const pkg = sourcePackage(source);
|
|
216
|
+
const sourceImportRe = pkg === null ? null : makeSourceImportRe(pkg);
|
|
208
217
|
for (const file of files) {
|
|
209
218
|
const sourceText = fs.readFileSync(file, 'utf8');
|
|
210
219
|
const collector = reporter.startFile();
|
|
@@ -233,7 +242,7 @@ function migrateFiles(source, files, reporter, io, options) {
|
|
|
233
242
|
// the file still imports it, we just couldn't rewrite it.
|
|
234
243
|
if (/['"](?:~?bulma\/)/.test(sourceText))
|
|
235
244
|
bulmaReferenced = true;
|
|
236
|
-
if (sourceImportRe
|
|
245
|
+
if (importsSource(sourceImportRe, sourceText))
|
|
237
246
|
sourceStillImported = true;
|
|
238
247
|
reporter.finishFile(file, false, collector.entries);
|
|
239
248
|
continue;
|
|
@@ -241,7 +250,7 @@ function migrateFiles(source, files, reporter, io, options) {
|
|
|
241
250
|
if (/['"](?:~?bulma\/)/.test(output ?? sourceText)) {
|
|
242
251
|
bulmaReferenced = true;
|
|
243
252
|
}
|
|
244
|
-
if (sourceImportRe
|
|
253
|
+
if (importsSource(sourceImportRe, output ?? sourceText)) {
|
|
245
254
|
sourceStillImported = true;
|
|
246
255
|
}
|
|
247
256
|
if (output !== null) {
|
|
@@ -260,13 +269,14 @@ function migrateFiles(source, files, reporter, io, options) {
|
|
|
260
269
|
*/
|
|
261
270
|
function reportUnsupportedFiles(source, targets, reporter, extensions) {
|
|
262
271
|
const unsupported = UNSUPPORTED_EXTENSIONS.filter(ext => !extensions.includes(ext));
|
|
263
|
-
|
|
272
|
+
const pkg = sourcePackage(source);
|
|
273
|
+
if (unsupported.length === 0 || pkg === null)
|
|
264
274
|
return false;
|
|
265
275
|
// Whether any unsupported file still references the source package. These
|
|
266
276
|
// are reported but never rewritten, so the reference survives the run —
|
|
267
277
|
// and the manifest pass must not remove the package out from under it.
|
|
268
278
|
let stillImported = false;
|
|
269
|
-
const importRe = makeSourceImportRe(
|
|
279
|
+
const importRe = makeSourceImportRe(pkg);
|
|
270
280
|
for (const file of collectFiles(targets, unsupported)) {
|
|
271
281
|
const text = fs.readFileSync(file, 'utf8');
|
|
272
282
|
// A substring match is not evidence of an import. `rbx` is three
|
|
@@ -283,7 +293,7 @@ function reportUnsupportedFiles(source, targets, reporter, extensions) {
|
|
|
283
293
|
file,
|
|
284
294
|
line,
|
|
285
295
|
rule: 'unsupported-file',
|
|
286
|
-
message: `imports ${
|
|
296
|
+
message: `imports ${pkg}, but ${path.extname(file)} files cannot be parsed by the codemod — migrate this file by hand`,
|
|
287
297
|
});
|
|
288
298
|
reporter.finishFile(file, false, collector.entries);
|
|
289
299
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `@allxsmith/bestax-bulma` import a migrated file ends up with.
|
|
3
|
+
*
|
|
4
|
+
* Every source does the same three things: seed the components an existing
|
|
5
|
+
* bestax import already binds (so the JSX reuses their locals), record which
|
|
6
|
+
* components the passes actually ask for, and then either merge the new ones
|
|
7
|
+
* into that existing import or write a fresh declaration. Where the fresh
|
|
8
|
+
* declaration goes is the caller's call; a library source puts it where the
|
|
9
|
+
* library's own import was.
|
|
10
|
+
*/
|
|
11
|
+
import type { TransformContext } from './jsx-utils.js';
|
|
12
|
+
export declare const BESTAX = "@allxsmith/bestax-bulma";
|
|
13
|
+
export interface BestaxImportState {
|
|
14
|
+
/** The existing declaration new specifiers merge into, if any. */
|
|
15
|
+
existing: any | undefined;
|
|
16
|
+
/** Components the existing declaration already binds as values. */
|
|
17
|
+
preExisting: Set<string>;
|
|
18
|
+
/** Components the passes asked for through `ctx.reserve`. */
|
|
19
|
+
requested: Set<string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Call once `ctx.reserve` is final and before any pass reserves a name: it
|
|
23
|
+
* wraps `reserve` to record requests and seeds `ctx.needed` from an existing
|
|
24
|
+
* bestax import.
|
|
25
|
+
*/
|
|
26
|
+
export declare function seedBestaxImport(ctx: TransformContext, root: any): BestaxImportState;
|
|
27
|
+
/** The fresh declaration for components not already imported, or null. */
|
|
28
|
+
export declare function buildBestaxImport(ctx: TransformContext, state: BestaxImportState): any | null;
|
|
29
|
+
/**
|
|
30
|
+
* Locals that bind a bestax VALUE once the import is written. A type-only
|
|
31
|
+
* specifier the seeding recorded, and nothing promoted, binds no value.
|
|
32
|
+
*/
|
|
33
|
+
export declare function bestaxValueLocals(ctx: TransformContext, state: BestaxImportState): Set<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Merge `fresh` into the existing bestax import, or insert it before
|
|
36
|
+
* `before` when there is none.
|
|
37
|
+
*/
|
|
38
|
+
export declare function placeBestaxImport(state: BestaxImportState, fresh: any | null, before: any): void;
|
|
39
|
+
/**
|
|
40
|
+
* A pruned declaration takes its comments with it — a licence header, an
|
|
41
|
+
* eslint directive. Hand them to `carrier` (the bestax import that survives),
|
|
42
|
+
* or to the next statement, or keep them where they were.
|
|
43
|
+
*/
|
|
44
|
+
export declare function carryPrunedComments(node: any, importPath: any, carrier: any | null): void;
|
|
45
|
+
//# sourceMappingURL=bestax-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bestax-import.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/bestax-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,eAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,QAAQ,EAAE,GAAG,GAAG,SAAS,CAAC;IAC1B,mEAAmE;IACnE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,6DAA6D;IAC7D,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,GAAG,GACR,iBAAiB,CA+CnB;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,iBAAiB,GACvB,GAAG,GAAG,IAAI,CAgBZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,iBAAiB,GACvB,GAAG,CAAC,MAAM,CAAC,CASb;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,GAAG,GAAG,IAAI,EACjB,MAAM,EAAE,GAAG,GACV,IAAI,CAyBN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,EACT,UAAU,EAAE,GAAG,EACf,OAAO,EAAE,GAAG,GAAG,IAAI,GAClB,IAAI,CAsBN"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `@allxsmith/bestax-bulma` import a migrated file ends up with.
|
|
3
|
+
*
|
|
4
|
+
* Every source does the same three things: seed the components an existing
|
|
5
|
+
* bestax import already binds (so the JSX reuses their locals), record which
|
|
6
|
+
* components the passes actually ask for, and then either merge the new ones
|
|
7
|
+
* into that existing import or write a fresh declaration. Where the fresh
|
|
8
|
+
* declaration goes is the caller's call; a library source puts it where the
|
|
9
|
+
* library's own import was.
|
|
10
|
+
*/
|
|
11
|
+
import { nameOf } from './imports.js';
|
|
12
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
13
|
+
export const BESTAX = '@allxsmith/bestax-bulma';
|
|
14
|
+
/**
|
|
15
|
+
* Call once `ctx.reserve` is final and before any pass reserves a name: it
|
|
16
|
+
* wraps `reserve` to record requests and seeds `ctx.needed` from an existing
|
|
17
|
+
* bestax import.
|
|
18
|
+
*/
|
|
19
|
+
export function seedBestaxImport(ctx, root) {
|
|
20
|
+
const { j } = ctx;
|
|
21
|
+
// Names the passes actually asked for. `ctx.needed` is also seeded from an
|
|
22
|
+
// existing bestax import's specifiers below (so JSX reuses their locals),
|
|
23
|
+
// and that seeding alone must not turn a type-only specifier into a value
|
|
24
|
+
// import nobody needed.
|
|
25
|
+
const requested = new Set();
|
|
26
|
+
const baseReserve = ctx.reserve;
|
|
27
|
+
ctx.reserve = name => {
|
|
28
|
+
requested.add(name);
|
|
29
|
+
return baseReserve(name);
|
|
30
|
+
};
|
|
31
|
+
// Only a declaration made entirely of NAMED specifiers can be merged into.
|
|
32
|
+
// `import * as Bulma from '@allxsmith/bestax-bulma'` matches the source too,
|
|
33
|
+
// and appending named specifiers to it emitted
|
|
34
|
+
// `import * as Bulma, { Box } from …` — not valid JavaScript, so the whole
|
|
35
|
+
// file failed to parse after a migration that reported success.
|
|
36
|
+
const existing = root
|
|
37
|
+
.find(j.ImportDeclaration, { source: { value: BESTAX } })
|
|
38
|
+
.paths()
|
|
39
|
+
.find((path) =>
|
|
40
|
+
// A type-only declaration cannot take a value specifier: merging a
|
|
41
|
+
// component into `import type { … }` erases it at runtime.
|
|
42
|
+
path.node.importKind !== 'type' &&
|
|
43
|
+
(path.node.specifiers ?? []).every((spec) => spec.type === 'ImportSpecifier'));
|
|
44
|
+
const preExisting = new Set();
|
|
45
|
+
if (existing) {
|
|
46
|
+
for (const spec of existing.node.specifiers ?? []) {
|
|
47
|
+
if (spec.type === 'ImportSpecifier' && spec.local) {
|
|
48
|
+
// The local name is reused either way, so the JSX never needs an
|
|
49
|
+
// alias. But an inline `type` specifier (`import { type Box }`) is
|
|
50
|
+
// not a value binding: it is not counted as already imported, so the
|
|
51
|
+
// component is written as a value below — onto this specifier, which
|
|
52
|
+
// keeps its name, rather than as a duplicate.
|
|
53
|
+
ctx.needed.set(nameOf(spec.imported), nameOf(spec.local));
|
|
54
|
+
if (spec.importKind !== 'type') {
|
|
55
|
+
preExisting.add(nameOf(spec.imported));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { existing, preExisting, requested };
|
|
61
|
+
}
|
|
62
|
+
/** The fresh declaration for components not already imported, or null. */
|
|
63
|
+
export function buildBestaxImport(ctx, state) {
|
|
64
|
+
const { j } = ctx;
|
|
65
|
+
const freshNames = [...ctx.needed.entries()]
|
|
66
|
+
.filter(([imported]) => state.requested.has(imported) && !state.preExisting.has(imported))
|
|
67
|
+
.sort((a, b) => a[0].localeCompare(b[0]));
|
|
68
|
+
return freshNames.length > 0
|
|
69
|
+
? j.importDeclaration(freshNames.map(([imported, local]) => j.importSpecifier(j.identifier(imported), j.identifier(local))), j.stringLiteral(BESTAX))
|
|
70
|
+
: null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Locals that bind a bestax VALUE once the import is written. A type-only
|
|
74
|
+
* specifier the seeding recorded, and nothing promoted, binds no value.
|
|
75
|
+
*/
|
|
76
|
+
export function bestaxValueLocals(ctx, state) {
|
|
77
|
+
return new Set([...ctx.needed.entries()]
|
|
78
|
+
.filter(([imported]) => state.requested.has(imported) || state.preExisting.has(imported))
|
|
79
|
+
.map(([, local]) => local));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Merge `fresh` into the existing bestax import, or insert it before
|
|
83
|
+
* `before` when there is none.
|
|
84
|
+
*/
|
|
85
|
+
export function placeBestaxImport(state, fresh, before) {
|
|
86
|
+
if (!fresh)
|
|
87
|
+
return;
|
|
88
|
+
if (!state.existing) {
|
|
89
|
+
before.insertBefore(fresh);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const current = state.existing.node.specifiers ?? [];
|
|
93
|
+
const appended = [];
|
|
94
|
+
for (const spec of fresh.specifiers) {
|
|
95
|
+
// A type-only specifier for the same name becomes the value
|
|
96
|
+
// import (a value import carries the type too); appending a
|
|
97
|
+
// second `Box` beside `type Box` would be a duplicate identifier.
|
|
98
|
+
const typeOnly = current.find((existingSpec) => existingSpec.type === 'ImportSpecifier' &&
|
|
99
|
+
existingSpec.importKind === 'type' &&
|
|
100
|
+
nameOf(existingSpec.imported) === nameOf(spec.imported));
|
|
101
|
+
if (typeOnly) {
|
|
102
|
+
typeOnly.importKind = null;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
appended.push(spec);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
state.existing.node.specifiers = [...current, ...appended];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A pruned declaration takes its comments with it — a licence header, an
|
|
112
|
+
* eslint directive. Hand them to `carrier` (the bestax import that survives),
|
|
113
|
+
* or to the next statement, or keep them where they were.
|
|
114
|
+
*/
|
|
115
|
+
export function carryPrunedComments(node, importPath, carrier) {
|
|
116
|
+
const comments = node.comments ?? [];
|
|
117
|
+
if (comments.length === 0)
|
|
118
|
+
return;
|
|
119
|
+
const body = importPath.parent?.node?.body ?? [];
|
|
120
|
+
const index = body.indexOf(node);
|
|
121
|
+
const target = carrier ?? (index >= 0 ? body[index + 1] : undefined);
|
|
122
|
+
if (target) {
|
|
123
|
+
target.comments = [...comments, ...(target.comments ?? [])];
|
|
124
|
+
}
|
|
125
|
+
else if (index > 0) {
|
|
126
|
+
// The import was the last statement: the comments stay where they
|
|
127
|
+
// were, after what precedes it.
|
|
128
|
+
const previous = body[index - 1];
|
|
129
|
+
previous.comments = [
|
|
130
|
+
...(previous.comments ?? []),
|
|
131
|
+
...comments.map((c) => ({ ...c, leading: false, trailing: true })),
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// The import was the only statement: the comments become the file's.
|
|
136
|
+
const program = importPath.parent?.node;
|
|
137
|
+
if (program)
|
|
138
|
+
program.comments = [...comments, ...(program.comments ?? [])];
|
|
139
|
+
}
|
|
140
|
+
node.comments = [];
|
|
141
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stylesheet-import pass every source runs before its JSX work.
|
|
3
|
+
*
|
|
4
|
+
* `--css bestax` (the default) converges every Bulma stylesheet import on the
|
|
5
|
+
* combined `bestax.css` bundle, which already carries the extras; `bulma`
|
|
6
|
+
* keeps plain Bulma v1 CSS and adds the extras import beside it; `keep`
|
|
7
|
+
* leaves the app's own Bulma import alone and only retargets a source
|
|
8
|
+
* library's stylesheet, which no longer resolves once the library is gone.
|
|
9
|
+
*
|
|
10
|
+
* What differs per source is the source's own stylesheet (react-bulma-components'
|
|
11
|
+
* v3 bundle, `rbx/index.css`; bloomer ships none) and anything the source
|
|
12
|
+
* handles before the shared rules (rbx's extension stylesheets).
|
|
13
|
+
*/
|
|
14
|
+
import type { CssMode } from '../../types.js';
|
|
15
|
+
import { type TransformContext } from './jsx-utils.js';
|
|
16
|
+
export interface StylesheetImportOptions {
|
|
17
|
+
/**
|
|
18
|
+
* The source library's own stylesheet, retargeted wherever Bulma's is:
|
|
19
|
+
* which specifiers are it, and how the keep-mode TODO names it (e.g.
|
|
20
|
+
* "rbx's CSS import"). One object, so a matcher never lacks its label.
|
|
21
|
+
*/
|
|
22
|
+
sourceCss?: {
|
|
23
|
+
is: (specifier: string) => boolean;
|
|
24
|
+
label: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Runs first for every import; returning true means the source handled it
|
|
28
|
+
* and the shared rules skip it.
|
|
29
|
+
*/
|
|
30
|
+
handleOwn?: (path: any, specifier: string) => boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function rewriteStylesheetImports(ctx: TransformContext, root: any, cssMode: CssMode, options?: StylesheetImportOptions): void;
|
|
33
|
+
//# sourceMappingURL=css-imports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-imports.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/css-imports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAuBhE,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CACvD;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,uBAA4B,GACpC,IAAI,CA4EN"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stylesheet-import pass every source runs before its JSX work.
|
|
3
|
+
*
|
|
4
|
+
* `--css bestax` (the default) converges every Bulma stylesheet import on the
|
|
5
|
+
* combined `bestax.css` bundle, which already carries the extras; `bulma`
|
|
6
|
+
* keeps plain Bulma v1 CSS and adds the extras import beside it; `keep`
|
|
7
|
+
* leaves the app's own Bulma import alone and only retargets a source
|
|
8
|
+
* library's stylesheet, which no longer resolves once the library is gone.
|
|
9
|
+
*
|
|
10
|
+
* What differs per source is the source's own stylesheet (react-bulma-components'
|
|
11
|
+
* v3 bundle, `rbx/index.css`; bloomer ships none) and anything the source
|
|
12
|
+
* handles before the shared rules (rbx's extension stylesheets).
|
|
13
|
+
*/
|
|
14
|
+
import { addTodo } from './jsx-utils.js';
|
|
15
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
16
|
+
const BULMA_CSS = 'bulma/css/bulma.min.css';
|
|
17
|
+
const BESTAX_CSS = '@allxsmith/bestax-bulma/bestax.css';
|
|
18
|
+
const EXTRAS_CSS = '@allxsmith/bestax-bulma/extras.css';
|
|
19
|
+
const BULMA_CSS_SPECIFIERS = new Set([
|
|
20
|
+
'bulma/css/bulma.css',
|
|
21
|
+
'bulma/css/bulma.min.css',
|
|
22
|
+
]);
|
|
23
|
+
const BESTAX_CSS_SPECIFIERS = new Set([
|
|
24
|
+
BESTAX_CSS,
|
|
25
|
+
'@allxsmith/bestax-bulma/bestax.min.css',
|
|
26
|
+
'@allxsmith/bestax-bulma/dist/bestax.css',
|
|
27
|
+
'@allxsmith/bestax-bulma/dist/bestax.min.css',
|
|
28
|
+
]);
|
|
29
|
+
const EXTRAS_CSS_SPECIFIERS = new Set([
|
|
30
|
+
EXTRAS_CSS,
|
|
31
|
+
'@allxsmith/bestax-bulma/dist/extras.css',
|
|
32
|
+
]);
|
|
33
|
+
export function rewriteStylesheetImports(ctx, root, cssMode, options = {}) {
|
|
34
|
+
const { j } = ctx;
|
|
35
|
+
const isSourceCss = options.sourceCss?.is ?? (() => false);
|
|
36
|
+
const specifierOf = (p) => String(p.node.source.value);
|
|
37
|
+
let sawBestaxCss = root
|
|
38
|
+
.find(j.ImportDeclaration)
|
|
39
|
+
.paths()
|
|
40
|
+
.some((p) => BESTAX_CSS_SPECIFIERS.has(specifierOf(p)));
|
|
41
|
+
// Whether some import in this file will become bestax.css, regardless of
|
|
42
|
+
// where it sits relative to an existing extras import.
|
|
43
|
+
const willAdoptBestaxCss = cssMode === 'bestax' &&
|
|
44
|
+
root
|
|
45
|
+
.find(j.ImportDeclaration)
|
|
46
|
+
.paths()
|
|
47
|
+
.some((p) => {
|
|
48
|
+
const specifier = specifierOf(p);
|
|
49
|
+
return isSourceCss(specifier) || BULMA_CSS_SPECIFIERS.has(specifier);
|
|
50
|
+
});
|
|
51
|
+
root.find(j.ImportDeclaration).forEach((path) => {
|
|
52
|
+
const source = specifierOf(path);
|
|
53
|
+
if (options.handleOwn?.(path, source))
|
|
54
|
+
return;
|
|
55
|
+
const isOwnCss = isSourceCss(source);
|
|
56
|
+
const isBulmaCss = BULMA_CSS_SPECIFIERS.has(source);
|
|
57
|
+
const isExtrasCss = EXTRAS_CSS_SPECIFIERS.has(source);
|
|
58
|
+
if (!isOwnCss && !isBulmaCss && !isExtrasCss)
|
|
59
|
+
return;
|
|
60
|
+
if (cssMode === 'bestax') {
|
|
61
|
+
if (isOwnCss || isBulmaCss) {
|
|
62
|
+
if (sawBestaxCss) {
|
|
63
|
+
path.prune(); // bestax.css already imported elsewhere in this file
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
path.node.source = j.stringLiteral(BESTAX_CSS);
|
|
67
|
+
sawBestaxCss = true;
|
|
68
|
+
}
|
|
69
|
+
ctx.dirty = true;
|
|
70
|
+
}
|
|
71
|
+
else if (isExtrasCss && (sawBestaxCss || willAdoptBestaxCss)) {
|
|
72
|
+
// bestax.css already contains the extras. `willAdoptBestaxCss` covers
|
|
73
|
+
// the case where the extras import comes FIRST in the file and the
|
|
74
|
+
// import that becomes bestax.css has not been visited yet —
|
|
75
|
+
// otherwise the extras survive alongside it and double-load.
|
|
76
|
+
path.prune();
|
|
77
|
+
ctx.dirty = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (cssMode === 'bulma') {
|
|
81
|
+
if (isOwnCss) {
|
|
82
|
+
path.node.source = j.stringLiteral(BULMA_CSS);
|
|
83
|
+
ctx.dirty = true;
|
|
84
|
+
}
|
|
85
|
+
if ((isOwnCss || isBulmaCss) && !sawBestaxCss) {
|
|
86
|
+
const hasExtras = root
|
|
87
|
+
.find(j.ImportDeclaration)
|
|
88
|
+
.paths()
|
|
89
|
+
.some((p) => EXTRAS_CSS_SPECIFIERS.has(specifierOf(p)));
|
|
90
|
+
if (!hasExtras) {
|
|
91
|
+
// Themed Radio/Checkbox need the bestax extras next to plain Bulma.
|
|
92
|
+
path.insertAfter(j.importDeclaration([], j.stringLiteral(EXTRAS_CSS)));
|
|
93
|
+
ctx.dirty = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (isOwnCss && options.sourceCss) {
|
|
98
|
+
// keep: minimal fix — the source's stylesheet goes with the source.
|
|
99
|
+
path.node.source = j.stringLiteral(BULMA_CSS);
|
|
100
|
+
addTodo(ctx, path, 'css', `replaced ${options.sourceCss.label} with '${BULMA_CSS}'; install bulma@^1 (see https://bestax.io/docs/guides/getting-started/installation)`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package.json steps every source's manifest pass takes once the source
|
|
3
|
+
* library itself is dealt with: bring in bestax-bulma, move the app's Bulma to
|
|
4
|
+
* v1, report peer ranges bestax-bulma cannot install beside, and swap the
|
|
5
|
+
* dead node-sass for dart-sass. Pure data-in/data-out, like the passes that
|
|
6
|
+
* call it: no package manager is ever invoked.
|
|
7
|
+
*/
|
|
8
|
+
import type { TodoCollector } from '../../types.js';
|
|
9
|
+
export declare const BULMA_RANGE = "^1.0.4";
|
|
10
|
+
export declare const DEP_SECTIONS: readonly ["dependencies", "devDependencies"];
|
|
11
|
+
type Section = (typeof DEP_SECTIONS)[number];
|
|
12
|
+
export interface Manifest {
|
|
13
|
+
/** The manifest being edited in place. */
|
|
14
|
+
next: Record<string, Record<string, string> | unknown>;
|
|
15
|
+
section(name: Section): Record<string, string> | undefined;
|
|
16
|
+
/** Record a change: it counts as an edit and lands in the report. */
|
|
17
|
+
note(message: string): void;
|
|
18
|
+
/** Report without counting as an edit. */
|
|
19
|
+
report(rule: string, message: string): void;
|
|
20
|
+
/** The edited manifest, or null when nothing changed. */
|
|
21
|
+
result(): Record<string, unknown> | null;
|
|
22
|
+
}
|
|
23
|
+
export declare function openManifest(filePath: string, pkg: Record<string, unknown>, collector: TodoCollector | undefined): Manifest;
|
|
24
|
+
/** @allxsmith/bestax-bulma comes in as a runtime dependency. */
|
|
25
|
+
export declare function addBestax(manifest: Manifest): void;
|
|
26
|
+
export interface BulmaOutcome {
|
|
27
|
+
/** The declared range before any bump, or null when none was declared. */
|
|
28
|
+
declared: string | null;
|
|
29
|
+
bumped: boolean;
|
|
30
|
+
added: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Bump a pre-1 Bulma range; add one only when sources still reference
|
|
34
|
+
* bulma/… directly (otherwise it arrives transitively via bestax-bulma).
|
|
35
|
+
*/
|
|
36
|
+
export declare function moveBulmaToV1(manifest: Manifest, bulmaReferenced: boolean | undefined): BulmaOutcome;
|
|
37
|
+
/**
|
|
38
|
+
* Report ranges bestax-bulma's peers cannot install beside. Report only: a
|
|
39
|
+
* React major and a Font Awesome major (whose icon names change) are the
|
|
40
|
+
* app's own migration steps.
|
|
41
|
+
*/
|
|
42
|
+
export declare function reportPeerRanges(manifest: Manifest): void;
|
|
43
|
+
/** node-sass is dead; dart-sass replaces it in the same section. */
|
|
44
|
+
export declare function replaceNodeSass(manifest: Manifest): void;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=deps-common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-common.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/deps-common.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,eAAO,MAAM,WAAW,WAAW,CAAC;AAIpC,eAAO,MAAM,YAAY,8CAA+C,CAAC;AACzE,KAAK,OAAO,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7C,MAAM,WAAW,QAAQ;IACvB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC3D,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0CAA0C;IAC1C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,yDAAyD;IACzD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,SAAS,EAAE,aAAa,GAAG,SAAS,GACnC,QAAQ,CAiBV;AAED,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAclD;AAED,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,OAAO,GAAG,SAAS,GACnC,YAAY,CA2Bd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAqBzD;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAexD"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package.json steps every source's manifest pass takes once the source
|
|
3
|
+
* library itself is dealt with: bring in bestax-bulma, move the app's Bulma to
|
|
4
|
+
* v1, report peer ranges bestax-bulma cannot install beside, and swap the
|
|
5
|
+
* dead node-sass for dart-sass. Pure data-in/data-out, like the passes that
|
|
6
|
+
* call it: no package manager is ever invoked.
|
|
7
|
+
*/
|
|
8
|
+
import { isPreV1 } from './semver-range.js';
|
|
9
|
+
const BESTAX_RANGE = '^5';
|
|
10
|
+
export const BULMA_RANGE = '^1.0.4';
|
|
11
|
+
// Bulma v1's sass tree uses `color.channel(…)` — needs dart-sass ≥ 1.79.
|
|
12
|
+
const SASS_RANGE = '^1.79.0';
|
|
13
|
+
export const DEP_SECTIONS = ['dependencies', 'devDependencies'];
|
|
14
|
+
export function openManifest(filePath, pkg, collector) {
|
|
15
|
+
const changes = [];
|
|
16
|
+
const next = pkg;
|
|
17
|
+
const report = (rule, message) => collector?.add({ file: filePath, line: null, rule, message });
|
|
18
|
+
return {
|
|
19
|
+
next,
|
|
20
|
+
section: name => (next[name] ?? undefined),
|
|
21
|
+
note: message => {
|
|
22
|
+
changes.push(message);
|
|
23
|
+
report('deps', message);
|
|
24
|
+
},
|
|
25
|
+
report,
|
|
26
|
+
result: () => changes.length > 0 ? next : null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** @allxsmith/bestax-bulma comes in as a runtime dependency. */
|
|
30
|
+
export function addBestax(manifest) {
|
|
31
|
+
const dependencies = (manifest.next.dependencies ??= {});
|
|
32
|
+
if (!dependencies['@allxsmith/bestax-bulma'] &&
|
|
33
|
+
!manifest.section('devDependencies')?.['@allxsmith/bestax-bulma']) {
|
|
34
|
+
dependencies['@allxsmith/bestax-bulma'] = BESTAX_RANGE;
|
|
35
|
+
manifest.note(`added @allxsmith/bestax-bulma ${BESTAX_RANGE} to dependencies`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Bump a pre-1 Bulma range; add one only when sources still reference
|
|
40
|
+
* bulma/… directly (otherwise it arrives transitively via bestax-bulma).
|
|
41
|
+
*/
|
|
42
|
+
export function moveBulmaToV1(manifest, bulmaReferenced) {
|
|
43
|
+
const outcome = { declared: null, bumped: false, added: false };
|
|
44
|
+
for (const name of DEP_SECTIONS) {
|
|
45
|
+
const deps = manifest.section(name);
|
|
46
|
+
if (deps?.bulma) {
|
|
47
|
+
outcome.declared = deps.bulma;
|
|
48
|
+
if (isPreV1(deps.bulma)) {
|
|
49
|
+
deps.bulma = BULMA_RANGE;
|
|
50
|
+
outcome.bumped = true;
|
|
51
|
+
manifest.note(`bumped bulma to ${BULMA_RANGE} in ${name} (was pre-1.0)`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (outcome.declared === null && bulmaReferenced) {
|
|
56
|
+
const dependencies = (manifest.next.dependencies ??= {});
|
|
57
|
+
dependencies.bulma = BULMA_RANGE;
|
|
58
|
+
outcome.added = true;
|
|
59
|
+
manifest.note(`added bulma ${BULMA_RANGE} to dependencies (sources import bulma/… directly)`);
|
|
60
|
+
}
|
|
61
|
+
return outcome;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Report ranges bestax-bulma's peers cannot install beside. Report only: a
|
|
65
|
+
* React major and a Font Awesome major (whose icon names change) are the
|
|
66
|
+
* app's own migration steps.
|
|
67
|
+
*/
|
|
68
|
+
export function reportPeerRanges(manifest) {
|
|
69
|
+
for (const name of DEP_SECTIONS) {
|
|
70
|
+
const range = manifest.section(name)?.react;
|
|
71
|
+
if (range && /^[~^]?(?:[0-9]|1[0-7])(?:[.x]|$)/.test(range.trim())) {
|
|
72
|
+
manifest.report('peer-deps', `react ${range} predates bestax-bulma's peer range (^18 || ^19) — upgrade react and react-dom to 18 or 19 before installing`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Font Awesome older than 6 conflicts with bestax-bulma's optional peer
|
|
76
|
+
// range and makes `npm install` fail with ERESOLVE.
|
|
77
|
+
for (const name of DEP_SECTIONS) {
|
|
78
|
+
const range = manifest.section(name)?.['@fortawesome/fontawesome-free'];
|
|
79
|
+
if (range && /^[~^]?[0-5](?:[.x]|$)/.test(range.trim())) {
|
|
80
|
+
manifest.report('peer-deps', `@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\``);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** node-sass is dead; dart-sass replaces it in the same section. */
|
|
85
|
+
export function replaceNodeSass(manifest) {
|
|
86
|
+
for (const name of DEP_SECTIONS) {
|
|
87
|
+
const deps = manifest.section(name);
|
|
88
|
+
if (deps && 'node-sass' in deps) {
|
|
89
|
+
delete deps['node-sass'];
|
|
90
|
+
manifest.note(`removed node-sass from ${name}`);
|
|
91
|
+
const sassDeclared = DEP_SECTIONS.some(s => manifest.section(s)?.sass);
|
|
92
|
+
if (!sassDeclared) {
|
|
93
|
+
deps.sass = SASS_RANGE;
|
|
94
|
+
manifest.note(`added sass ${SASS_RANGE} to ${name} (replaces node-sass)`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -14,8 +14,11 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { StylesTransform } from '../../types.js';
|
|
16
16
|
export interface StylesConfig {
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* npm package name of the source library, e.g. `rbx`. Omitted for a source
|
|
19
|
+
* with no package, whose stylesheets only ever import Bulma itself.
|
|
20
|
+
*/
|
|
21
|
+
packageName?: string;
|
|
19
22
|
/** URL of that source's migration guide, linked from every TODO. */
|
|
20
23
|
guideUrl: string;
|
|
21
24
|
/**
|
|
@@ -32,6 +35,7 @@ export interface StylesConfig {
|
|
|
32
35
|
* `packageName` drives two regexes — one matching any `@import` of that
|
|
33
36
|
* package, one narrowing to its *root* stylesheet (which becomes a Bulma v1
|
|
34
37
|
* root rather than being dropped). Everything else is Bulma-side and shared.
|
|
38
|
+
* Without a package neither can match, and only the Bulma rewriting runs.
|
|
35
39
|
*/
|
|
36
40
|
export declare function makeStylesTransform(config: StylesConfig): StylesTransform;
|
|
37
41
|
//# sourceMappingURL=make-styles-transform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-styles-transform.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/make-styles-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,gBAAgB,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B
|
|
1
|
+
{"version":3,"file":"make-styles-transform.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/make-styles-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,gBAAgB,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC;AAyMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAsVzE"}
|
|
@@ -197,10 +197,14 @@ function report(collector, file, line, rule, message) {
|
|
|
197
197
|
* `packageName` drives two regexes — one matching any `@import` of that
|
|
198
198
|
* package, one narrowing to its *root* stylesheet (which becomes a Bulma v1
|
|
199
199
|
* root rather than being dropped). Everything else is Bulma-side and shared.
|
|
200
|
+
* Without a package neither can match, and only the Bulma rewriting runs.
|
|
200
201
|
*/
|
|
201
202
|
export function makeStylesTransform(config) {
|
|
202
203
|
const { packageName, guideUrl: GUIDE } = config;
|
|
203
|
-
|
|
204
|
+
// `packageName` is interpolated into messages only after one of these
|
|
205
|
+
// matched, so the no-package case never reaches them.
|
|
206
|
+
const NEVER = /(?!)/;
|
|
207
|
+
const pkg = packageName?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
204
208
|
// Already regex fragments — see StylesConfig.
|
|
205
209
|
const roots = config.rootStylesheetSuffixes.join('|');
|
|
206
210
|
/**
|
|
@@ -210,11 +214,15 @@ export function makeStylesTransform(config) {
|
|
|
210
214
|
* and SOURCE_ROOT_STYLESHEET below already accepts that bare form — so
|
|
211
215
|
* requiring the slash here made the bare case unreachable.
|
|
212
216
|
*/
|
|
213
|
-
const SOURCE_STYLE_IMPORT =
|
|
217
|
+
const SOURCE_STYLE_IMPORT = pkg === undefined
|
|
218
|
+
? NEVER
|
|
219
|
+
: new RegExp(`^(\\s*)@import\\s+(['"])((?:\\.\\.?/)+node_modules/|~)?${pkg}(?:/[^'"]*)?\\2\\s*;?\\s*(?://[^\\n]*)?\\s*$`);
|
|
214
220
|
/** Cheap "is this file even about us?" pre-filter (see the guard below). */
|
|
215
|
-
const SOURCE_MENTION = new RegExp(pkg);
|
|
221
|
+
const SOURCE_MENTION = pkg === undefined ? NEVER : new RegExp(pkg);
|
|
216
222
|
/** …narrowed to the ones that stand in for a whole Bulma root. */
|
|
217
|
-
const SOURCE_ROOT_STYLESHEET =
|
|
223
|
+
const SOURCE_ROOT_STYLESHEET = pkg === undefined
|
|
224
|
+
? NEVER
|
|
225
|
+
: new RegExp(`^\\s*@import\\s+(['"])(?:(?:\\.\\.?/)+node_modules/|~)?${pkg}${roots ? `(?:${roots})?` : ''}\\1\\s*;?\\s*(?://[^\\n]*)?\\s*$`);
|
|
218
226
|
const transformStyles = (filePath, source, collector, options) => {
|
|
219
227
|
const cssMode = options.cssMode ?? 'bestax';
|
|
220
228
|
// Cheap pre-filter. It must accept a file that names only the SOURCE
|
|
@@ -29,7 +29,7 @@ export declare function alignTarget(ctx: TransformContext, path: ASTPath<any>, e
|
|
|
29
29
|
* bound for a plain HTML element (they only exist on bestax components),
|
|
30
30
|
* leaving a TODO when any were dropped.
|
|
31
31
|
*/
|
|
32
|
-
export declare function makeStripModifierProps(universalProps: Record<string, PropAction>, responsiveBreakpoints: Record<string, string | null
|
|
32
|
+
export declare function makeStripModifierProps(universalProps: Record<string, PropAction>, responsiveBreakpoints: Record<string, string | null>, refProp?: string): (ctx: TransformContext, path: ASTPath<any>, attrs: any[], where: string) => any[];
|
|
33
33
|
/**
|
|
34
34
|
* Consume the element's `className` so a plain-element rewrite can merge it
|
|
35
35
|
* with its hard-coded Bulma class instead of dropping it. A dynamic value
|