@entur/typography 1.10.0-beta.8 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -17
- package/dist/BaseHeading.d.ts +1 -1
- package/dist/Blockquote.d.ts +3 -4
- package/dist/CodeText.d.ts +1 -1
- package/dist/EmphasizedText.d.ts +1 -1
- package/dist/Heading1.d.ts +1 -1
- package/dist/Heading2.d.ts +1 -1
- package/dist/Heading3.d.ts +1 -1
- package/dist/Heading4.d.ts +1 -1
- package/dist/Heading5.d.ts +1 -1
- package/dist/Heading6.d.ts +1 -1
- package/dist/Label.d.ts +1 -1
- package/dist/LeadParagraph.d.ts +1 -1
- package/dist/Link.d.ts +1 -1
- package/dist/ListItem.d.ts +1 -1
- package/dist/NumberedList.d.ts +1 -1
- package/dist/Paragraph.d.ts +1 -1
- package/dist/PreformattedText.d.ts +1 -1
- package/dist/SmallText.d.ts +1 -1
- package/dist/StrongText.d.ts +1 -1
- package/dist/SubLabel.d.ts +1 -1
- package/dist/SubParagraph.d.ts +1 -1
- package/dist/UnorderedList.d.ts +1 -1
- package/dist/beta/cjs/components/Blockquote.cjs +29 -0
- package/dist/beta/cjs/components/Blockquote.cjs.map +1 -0
- package/dist/beta/cjs/components/Heading.cjs +37 -0
- package/dist/beta/cjs/components/Heading.cjs.map +1 -0
- package/dist/beta/cjs/components/Link.cjs +41 -0
- package/dist/beta/cjs/components/Link.cjs.map +1 -0
- package/dist/beta/cjs/components/ListItem.cjs +33 -0
- package/dist/beta/cjs/components/ListItem.cjs.map +1 -0
- package/dist/beta/cjs/components/NumberedList.cjs +32 -0
- package/dist/beta/cjs/components/NumberedList.cjs.map +1 -0
- package/dist/beta/cjs/components/Text.cjs +36 -0
- package/dist/beta/cjs/components/Text.cjs.map +1 -0
- package/dist/beta/cjs/components/UnorderedList.cjs +29 -0
- package/dist/beta/cjs/components/UnorderedList.cjs.map +1 -0
- package/dist/beta/cjs/index.cjs +18 -0
- package/dist/beta/cjs/index.cjs.map +1 -0
- package/dist/beta/cjs/utils/utils.cjs +77 -0
- package/dist/beta/cjs/utils/utils.cjs.map +1 -0
- package/dist/beta/esm/components/Blockquote.mjs +29 -0
- package/dist/beta/esm/components/Blockquote.mjs.map +1 -0
- package/dist/beta/esm/components/Heading.mjs +37 -0
- package/dist/beta/esm/components/Heading.mjs.map +1 -0
- package/dist/beta/esm/components/Link.mjs +41 -0
- package/dist/beta/esm/components/Link.mjs.map +1 -0
- package/dist/beta/esm/components/ListItem.mjs +33 -0
- package/dist/beta/esm/components/ListItem.mjs.map +1 -0
- package/dist/beta/esm/components/NumberedList.mjs +32 -0
- package/dist/beta/esm/components/NumberedList.mjs.map +1 -0
- package/dist/beta/esm/components/Text.mjs +36 -0
- package/dist/beta/esm/components/Text.mjs.map +1 -0
- package/dist/beta/esm/components/UnorderedList.mjs +29 -0
- package/dist/beta/esm/components/UnorderedList.mjs.map +1 -0
- package/dist/beta/esm/index.mjs +18 -0
- package/dist/beta/esm/index.mjs.map +1 -0
- package/dist/beta/esm/utils/utils.mjs +77 -0
- package/dist/beta/esm/utils/utils.mjs.map +1 -0
- package/dist/beta/styles/components/heading.css +458 -0
- package/dist/beta/styles/components/text.css +959 -0
- package/dist/beta/types/components/Blockquote.d.ts +12 -0
- package/dist/beta/{Heading.d.ts → types/components/Heading.d.ts} +2 -3
- package/dist/beta/types/components/Link.d.ts +22 -0
- package/dist/beta/types/components/ListItem.d.ts +22 -0
- package/dist/beta/types/components/NumberedList.d.ts +22 -0
- package/dist/beta/{Text.d.ts → types/components/Text.d.ts} +2 -3
- package/dist/beta/types/components/UnorderedList.d.ts +20 -0
- package/dist/beta/types/index.d.ts +8 -0
- package/dist/beta/types/utils/utils.d.ts +13 -0
- package/dist/index.d.ts +0 -5
- package/dist/styles.css +162 -820
- package/dist/typography.cjs.js +416 -0
- package/dist/typography.cjs.js.map +1 -0
- package/dist/typography.esm.js +392 -454
- package/dist/typography.esm.js.map +1 -1
- package/fonts/Entur-Nationale-Demibold.eot +0 -0
- package/fonts/Entur-Nationale-Demibold.woff +0 -0
- package/fonts/Entur-Nationale-Demibold.woff2 +0 -0
- package/fonts/Entur-Nationale-DemiboldItalic.eot +0 -0
- package/fonts/Entur-Nationale-DemiboldItalic.woff +0 -0
- package/fonts/Entur-Nationale-DemiboldItalic.woff2 +0 -0
- package/fonts/Entur-Nationale-Italic.eot +0 -0
- package/fonts/Entur-Nationale-Italic.woff +0 -0
- package/fonts/Entur-Nationale-Italic.woff2 +0 -0
- package/fonts/Entur-Nationale-Light.eot +0 -0
- package/fonts/Entur-Nationale-Light.woff +0 -0
- package/fonts/Entur-Nationale-Light.woff2 +0 -0
- package/fonts/Entur-Nationale-LightItalic.eot +0 -0
- package/fonts/Entur-Nationale-LightItalic.woff +0 -0
- package/fonts/Entur-Nationale-LightItalic.woff2 +0 -0
- package/fonts/Entur-Nationale-Medium.eot +0 -0
- package/fonts/Entur-Nationale-Medium.woff +0 -0
- package/fonts/Entur-Nationale-Medium.woff2 +0 -0
- package/fonts/Entur-Nationale-MediumItalic.eot +0 -0
- package/fonts/Entur-Nationale-MediumItalic.woff +0 -0
- package/fonts/Entur-Nationale-MediumItalic.woff2 +0 -0
- package/fonts/Entur-Nationale-Regular.eot +0 -0
- package/fonts/Entur-Nationale-Regular.woff +0 -0
- package/fonts/Entur-Nationale-Regular.woff2 +0 -0
- package/package.json +59 -19
- package/scripts/migrate-typography.js +415 -178
- package/dist/beta/BlockquoteBeta.d.ts +0 -12
- package/dist/beta/LinkBeta.d.ts +0 -16
- package/dist/beta/index.d.ts +0 -6
- package/dist/beta/utils.d.ts +0 -9
- package/dist/index.js +0 -8
- package/dist/typography.cjs.development.js +0 -508
- package/dist/typography.cjs.development.js.map +0 -1
- package/dist/typography.cjs.production.min.js +0 -2
- package/dist/typography.cjs.production.min.js.map +0 -1
- /package/dist/beta/{types.d.ts → types/types.d.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
+
* NOTICE: This script is generated using AI with human guidance.
|
|
4
5
|
* Typography Migration Script
|
|
5
6
|
*
|
|
6
7
|
* This script helps you migrate from old typography components to new beta typography.
|
|
@@ -11,28 +12,38 @@
|
|
|
11
12
|
* - Updates import paths AND component usage
|
|
12
13
|
* - Replaces old components with beta components
|
|
13
14
|
* - CONSEQUENCES:
|
|
14
|
-
* * <Heading1> becomes <Heading as="h1" variant="title-1">
|
|
15
|
+
* * <Heading1-6> becomes <Heading as="h1-6" variant="title-1|title-2|subtitle-1|subtitle-2|section-1|section-2">
|
|
15
16
|
* * <Paragraph> becomes <Text variant="paragraph">
|
|
16
|
-
* * <
|
|
17
|
-
* *
|
|
17
|
+
* * <LeadParagraph> becomes <Text variant="leading">
|
|
18
|
+
* * <SmallText> becomes <Text variant="subparagraph">
|
|
19
|
+
* * <StrongText> becomes <Text as="strong" weight="bold">
|
|
20
|
+
* * <SubLabel> becomes <Text variant="sublabel">
|
|
21
|
+
* * <SubParagraph> becomes <Text variant="subparagraph">
|
|
22
|
+
* * <Label> becomes <Text variant="label"> (or <Text as="label" variant="label"> if htmlFor prop exists)
|
|
23
|
+
* * <EmphasizedText> becomes <Text variant="emphasized">
|
|
24
|
+
* * <CodeText> becomes <Text variant="code-text">
|
|
25
|
+
* * <PreformattedText> becomes <Text variant="preformatted-text">
|
|
26
|
+
* * <Link> becomes <Link> (from @entur/typography/beta)
|
|
27
|
+
* * <Blockquote> becomes <Blockquote> (from @entur/typography/beta)
|
|
28
|
+
* * <BlockquoteFooter> becomes <BlockquoteFooter> (from @entur/typography/beta)
|
|
29
|
+
* * <UnorderedList> becomes <UnorderedList> (from @entur/typography/beta)
|
|
30
|
+
* * <NumberedList> becomes <NumberedList> (from @entur/typography/beta)
|
|
31
|
+
* * <ListItem> becomes <ListItem> (from @entur/typography/beta)
|
|
32
|
+
* * Import paths change from @entur/typography to @entur/typography/beta
|
|
33
|
+
* * Props may need updates (e.g., margin becomes spacing)
|
|
18
34
|
* * Styling classes may change
|
|
19
35
|
* * Test thoroughly after migration!
|
|
20
36
|
*
|
|
21
|
-
|
|
22
|
-
* - Only updates import paths from '@entur/typography' to '@entur/typography'
|
|
23
|
-
* - Keeps your existing component usage unchanged
|
|
24
|
-
* - Minimal risk, allows gradual migration
|
|
25
|
-
* - You can manually update components later
|
|
37
|
+
|
|
26
38
|
*
|
|
27
39
|
* Usage:
|
|
28
40
|
* 1. Run this script in your project root
|
|
29
|
-
* 2. Choose your migration mode (complete
|
|
41
|
+
* 2. Choose your migration mode (complete)
|
|
30
42
|
* 3. Update your styles as needed
|
|
31
43
|
* 4. Test your application thoroughly
|
|
32
44
|
*
|
|
33
45
|
* Options:
|
|
34
46
|
* --dry-run Show what would be changed without modifying files
|
|
35
|
-
* --import-only Import-only migration: update import paths only
|
|
36
47
|
*
|
|
37
48
|
* Environment Variables:
|
|
38
49
|
* TYPOGRAPHY_MIGRATION_DIRS Comma-separated list of directories to scan
|
|
@@ -46,13 +57,19 @@
|
|
|
46
57
|
*
|
|
47
58
|
*/
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
import fs from 'fs';
|
|
61
|
+
import path from 'path';
|
|
62
|
+
import { fileURLToPath } from 'url';
|
|
63
|
+
|
|
64
|
+
// Get __dirname equivalent for ES modules
|
|
65
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
66
|
+
const __dirname = path.dirname(__filename);
|
|
51
67
|
|
|
52
68
|
// Check if glob is available
|
|
53
69
|
let glob;
|
|
54
70
|
try {
|
|
55
|
-
|
|
71
|
+
const globModule = await import('glob');
|
|
72
|
+
glob = globModule.default || globModule;
|
|
56
73
|
} catch (error) {
|
|
57
74
|
console.error(
|
|
58
75
|
'❌ Error: The "glob" package is required to run this migration script.',
|
|
@@ -70,7 +87,7 @@ try {
|
|
|
70
87
|
|
|
71
88
|
// Configuration
|
|
72
89
|
const OLD_IMPORT = '@entur/typography';
|
|
73
|
-
const BETA_IMPORT = '@entur/typography';
|
|
90
|
+
const BETA_IMPORT = '@entur/typography/beta';
|
|
74
91
|
|
|
75
92
|
// Enhanced warning detection patterns - only truly problematic patterns
|
|
76
93
|
const PROBLEMATIC_PATTERNS = {
|
|
@@ -123,6 +140,7 @@ const MIGRATION_FOLDERS = [
|
|
|
123
140
|
'app/**',
|
|
124
141
|
'apps/**',
|
|
125
142
|
'components/**',
|
|
143
|
+
'packages/**',
|
|
126
144
|
'pages/**',
|
|
127
145
|
'lib/**',
|
|
128
146
|
'utils/**',
|
|
@@ -342,15 +360,20 @@ const COMPONENT_MAPPING = {
|
|
|
342
360
|
Heading6: { component: 'Heading', as: 'h6', variant: 'section-2' },
|
|
343
361
|
Paragraph: { component: 'Text', variant: 'paragraph' },
|
|
344
362
|
LeadParagraph: { component: 'Text', variant: 'leading' },
|
|
345
|
-
SmallText: { component: 'Text', variant: 'subparagraph'
|
|
346
|
-
StrongText: { component: 'Text',
|
|
347
|
-
SubLabel: { component: 'Text', variant: 'sublabel'
|
|
363
|
+
SmallText: { component: 'Text', variant: 'subparagraph' },
|
|
364
|
+
StrongText: { component: 'Text', as: 'strong', weight: 'bold' },
|
|
365
|
+
SubLabel: { component: 'Text', variant: 'sublabel' },
|
|
348
366
|
SubParagraph: { component: 'Text', variant: 'subparagraph' },
|
|
349
367
|
Label: { component: 'Text', variant: 'label' },
|
|
350
368
|
EmphasizedText: { component: 'Text', variant: 'emphasized' },
|
|
351
369
|
CodeText: { component: 'Text', variant: 'code-text' },
|
|
352
|
-
|
|
353
|
-
|
|
370
|
+
PreformattedText: { component: 'Text', variant: 'preformatted-text' },
|
|
371
|
+
Link: { component: 'Link' }, // Convert Link to beta Link
|
|
372
|
+
Blockquote: { component: 'Blockquote' }, // Convert Blockquote to beta Blockquote
|
|
373
|
+
BlockquoteFooter: { component: 'BlockquoteFooter' }, // Convert BlockquoteFooter to beta BlockquoteFooter
|
|
374
|
+
UnorderedList: { component: 'UnorderedList' },
|
|
375
|
+
NumberedList: { component: 'NumberedList' },
|
|
376
|
+
ListItem: { component: 'ListItem' },
|
|
354
377
|
};
|
|
355
378
|
|
|
356
379
|
// Props mapping for migration
|
|
@@ -359,17 +382,43 @@ const PROPS_MAPPING = {
|
|
|
359
382
|
};
|
|
360
383
|
|
|
361
384
|
// Spacing value mapping from old margin to new spacing
|
|
385
|
+
// Based on the actual CSS classes in src/beta/styles.scss
|
|
386
|
+
// and the old margin prop values: "top" | "bottom" | "both" | "none"
|
|
362
387
|
const SPACING_MAPPING = {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
388
|
+
// Old margin values mapped to new spacing values
|
|
389
|
+
none: 'none', // No spacing
|
|
390
|
+
top: 'md-top', // Top margin only (medium size)
|
|
391
|
+
bottom: 'md-bottom', // Bottom margin only (medium size)
|
|
392
|
+
both: 'md', // Both top and bottom margins (medium size)
|
|
393
|
+
|
|
394
|
+
// Additional spacing values for more granular control
|
|
395
|
+
// These weren't in the old margin prop but are available in new spacing
|
|
396
|
+
left: 'md-left', // Left margin (medium size)
|
|
397
|
+
right: 'md-right', // Right margin (medium size)
|
|
398
|
+
|
|
399
|
+
// Size-based spacing (applies to both top and bottom)
|
|
368
400
|
xs: 'xs',
|
|
369
401
|
sm: 'sm',
|
|
370
402
|
md: 'md',
|
|
371
403
|
lg: 'lg',
|
|
372
404
|
xl: 'xl',
|
|
405
|
+
|
|
406
|
+
// Specific directional spacing with sizes
|
|
407
|
+
'xs-top': 'xs-top',
|
|
408
|
+
'xs-bottom': 'xs-bottom',
|
|
409
|
+
'sm-top': 'sm-top',
|
|
410
|
+
'sm-bottom': 'sm-bottom',
|
|
411
|
+
'md-top': 'md-top',
|
|
412
|
+
'md-bottom': 'md-bottom',
|
|
413
|
+
'lg-top': 'lg-top',
|
|
414
|
+
'lg-bottom': 'lg-bottom',
|
|
415
|
+
'xl-top': 'xl-top',
|
|
416
|
+
'xl-bottom': 'xl-bottom',
|
|
417
|
+
|
|
418
|
+
// Extra small variants
|
|
419
|
+
xs2: 'xs2',
|
|
420
|
+
'xs2-top': 'xs2-top',
|
|
421
|
+
'xs2-bottom': 'xs2-bottom',
|
|
373
422
|
};
|
|
374
423
|
|
|
375
424
|
// Import patterns to handle
|
|
@@ -378,35 +427,40 @@ const IMPORT_PATTERNS = [
|
|
|
378
427
|
/from\s+['"`]@entur\/typography\/dist['"`]/g,
|
|
379
428
|
/from\s+['"`]@entur\/typography\/dist\/index['"`]/g,
|
|
380
429
|
/from\s+['"`]@entur\/typography\/dist\/styles\.css['"`]/g,
|
|
430
|
+
/from\s+['"`]@entur\/typography\/styles['"`]/g,
|
|
381
431
|
];
|
|
382
432
|
|
|
383
433
|
// Parse JSX props more robustly
|
|
384
434
|
function parseJSXProps(propsString) {
|
|
385
435
|
if (!propsString || !propsString.trim()) {
|
|
386
|
-
return { props: {}, warnings: [] };
|
|
436
|
+
return { props: {}, warnings: [], spreadProps: [] };
|
|
387
437
|
}
|
|
388
438
|
|
|
389
439
|
const props = {};
|
|
390
440
|
const warnings = [];
|
|
391
|
-
const
|
|
392
|
-
|
|
441
|
+
const spreadProps = []; // Track spread props separately
|
|
442
|
+
const originalSyntax = {}; // Track original JSX syntax for each prop
|
|
393
443
|
|
|
394
444
|
try {
|
|
395
445
|
// Parse props manually to handle complex cases
|
|
396
446
|
let remaining = propsString.trim();
|
|
397
|
-
let lastRemainingLength = remaining.length;
|
|
398
447
|
|
|
399
|
-
|
|
400
|
-
|
|
448
|
+
// First, extract all spread props
|
|
449
|
+
const spreadRegex = /\.\.\.\{?(\w+)\}?/g;
|
|
450
|
+
let spreadMatch;
|
|
451
|
+
while ((spreadMatch = spreadRegex.exec(remaining)) !== null) {
|
|
452
|
+
spreadProps.push(spreadMatch[1]);
|
|
453
|
+
}
|
|
401
454
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
455
|
+
// Remove spread props from the string to parse regular props
|
|
456
|
+
remaining = remaining.replace(/\.\.\.\{?(\w+)\}?/g, '');
|
|
457
|
+
|
|
458
|
+
// Now parse regular props
|
|
459
|
+
while (remaining.trim().length > 0) {
|
|
460
|
+
// Skip whitespace
|
|
461
|
+
remaining = remaining.replace(/^\s+/, '');
|
|
408
462
|
|
|
409
|
-
// Match prop name
|
|
463
|
+
// Match prop name
|
|
410
464
|
const nameMatch = remaining.match(/^(\w+)=/);
|
|
411
465
|
if (!nameMatch) break;
|
|
412
466
|
|
|
@@ -416,7 +470,7 @@ function parseJSXProps(propsString) {
|
|
|
416
470
|
|
|
417
471
|
// Match prop value
|
|
418
472
|
if (remaining.startsWith('"') || remaining.startsWith("'")) {
|
|
419
|
-
// String value
|
|
473
|
+
// String value
|
|
420
474
|
const quote = remaining[0];
|
|
421
475
|
const endQuoteIndex = remaining.indexOf(quote, 1);
|
|
422
476
|
if (endQuoteIndex === -1) {
|
|
@@ -426,14 +480,14 @@ function parseJSXProps(propsString) {
|
|
|
426
480
|
|
|
427
481
|
const propValue = remaining.substring(1, endQuoteIndex);
|
|
428
482
|
props[propName] = propValue;
|
|
483
|
+
originalSyntax[propName] = 'string'; // Mark as string literal
|
|
429
484
|
remaining = remaining.substring(endQuoteIndex + 1);
|
|
430
485
|
} else if (remaining.startsWith('{')) {
|
|
431
|
-
// Object value - find matching closing brace
|
|
486
|
+
// Object value - find matching closing brace
|
|
432
487
|
let braceCount = 0;
|
|
433
488
|
let endIndex = -1;
|
|
434
|
-
const maxSearchLength = Math.min(remaining.length, 1000); // Limit search length
|
|
435
489
|
|
|
436
|
-
for (let i = 0; i <
|
|
490
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
437
491
|
if (remaining[i] === '{') braceCount++;
|
|
438
492
|
if (remaining[i] === '}') {
|
|
439
493
|
braceCount--;
|
|
@@ -451,25 +505,23 @@ function parseJSXProps(propsString) {
|
|
|
451
505
|
|
|
452
506
|
const propValue = remaining.substring(1, endIndex);
|
|
453
507
|
props[propName] = propValue;
|
|
508
|
+
originalSyntax[propName] = 'jsx'; // Mark as JSX expression
|
|
454
509
|
remaining = remaining.substring(endIndex + 1);
|
|
455
510
|
} else {
|
|
456
|
-
// Boolean prop
|
|
511
|
+
// Boolean prop
|
|
457
512
|
props[propName] = true;
|
|
513
|
+
originalSyntax[propName] = 'boolean'; // Mark as boolean
|
|
458
514
|
break;
|
|
459
515
|
}
|
|
460
516
|
|
|
461
|
-
// Skip whitespace
|
|
517
|
+
// Skip whitespace
|
|
462
518
|
remaining = remaining.replace(/^\s+/, '');
|
|
463
519
|
}
|
|
464
|
-
|
|
465
|
-
if (iterationCount >= MAX_ITERATIONS) {
|
|
466
|
-
warnings.push(`Maximum parsing iterations (${MAX_ITERATIONS}) reached`);
|
|
467
|
-
}
|
|
468
520
|
} catch (error) {
|
|
469
521
|
warnings.push(`Failed to parse props: ${error.message}`);
|
|
470
522
|
}
|
|
471
523
|
|
|
472
|
-
return { props, warnings };
|
|
524
|
+
return { props, warnings, spreadProps, originalSyntax };
|
|
473
525
|
}
|
|
474
526
|
|
|
475
527
|
// Migrate props from old to new format
|
|
@@ -487,11 +539,12 @@ function migrateProps(props, oldComponent) {
|
|
|
487
539
|
`Migrated 'margin="${props.margin}"' to 'spacing="${newSpacing}"'`,
|
|
488
540
|
);
|
|
489
541
|
} else {
|
|
490
|
-
// Unknown margin value -
|
|
491
|
-
|
|
542
|
+
// Unknown margin value - suggest alternatives
|
|
543
|
+
const suggestions = getSpacingSuggestions(props.margin);
|
|
544
|
+
migratedProps.spacing = props.margin; // Keep original value for now
|
|
492
545
|
delete migratedProps.margin;
|
|
493
546
|
warnings.push(
|
|
494
|
-
`Migrated 'margin="${props.margin}"' to 'spacing="${props.margin}"' (unknown value
|
|
547
|
+
`Migrated 'margin="${props.margin}"' to 'spacing="${props.margin}"' (unknown value). ${suggestions}`,
|
|
495
548
|
);
|
|
496
549
|
}
|
|
497
550
|
}
|
|
@@ -518,8 +571,55 @@ function migrateProps(props, oldComponent) {
|
|
|
518
571
|
return { props: migratedProps, warnings };
|
|
519
572
|
}
|
|
520
573
|
|
|
574
|
+
// Helper function to suggest spacing alternatives for unknown margin values
|
|
575
|
+
function getSpacingSuggestions(unknownMargin) {
|
|
576
|
+
const suggestions = [];
|
|
577
|
+
|
|
578
|
+
// Check if it might be one of the old margin values
|
|
579
|
+
if (['top', 'bottom', 'both', 'none'].includes(unknownMargin)) {
|
|
580
|
+
suggestions.push(
|
|
581
|
+
`"${unknownMargin}" is a valid old margin value and will be migrated correctly.`,
|
|
582
|
+
);
|
|
583
|
+
return suggestions.join(' ');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Check if it might be a directional value
|
|
587
|
+
if (
|
|
588
|
+
unknownMargin.includes('top') ||
|
|
589
|
+
unknownMargin.includes('bottom') ||
|
|
590
|
+
unknownMargin.includes('left') ||
|
|
591
|
+
unknownMargin.includes('right')
|
|
592
|
+
) {
|
|
593
|
+
suggestions.push(
|
|
594
|
+
'Consider using directional spacing like "md-top", "sm-bottom", etc.',
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Check if it might be a size value
|
|
599
|
+
if (['xs', 'sm', 'md', 'lg', 'xl'].includes(unknownMargin)) {
|
|
600
|
+
suggestions.push(
|
|
601
|
+
'Consider using size-based spacing like "xs", "sm", "md", "lg", "xl".',
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Check if it might be a specific variant
|
|
606
|
+
if (unknownMargin.includes('xs2')) {
|
|
607
|
+
suggestions.push(
|
|
608
|
+
'Consider using "xs2", "xs2-top", or "xs2-bottom" for extra small spacing.',
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (suggestions.length === 0) {
|
|
613
|
+
suggestions.push(
|
|
614
|
+
'Old margin values: "none", "top", "bottom", "both". New spacing values: "xs", "sm", "md", "lg", "xl", and directional variants.',
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return suggestions.join(' ');
|
|
619
|
+
}
|
|
620
|
+
|
|
521
621
|
// Convert props object back to JSX string
|
|
522
|
-
function propsToString(props) {
|
|
622
|
+
function propsToString(props, originalSyntax = {}) {
|
|
523
623
|
if (!props || Object.keys(props).length === 0) {
|
|
524
624
|
return '';
|
|
525
625
|
}
|
|
@@ -528,20 +628,46 @@ function propsToString(props) {
|
|
|
528
628
|
' ' +
|
|
529
629
|
Object.entries(props)
|
|
530
630
|
.map(([key, value]) => {
|
|
531
|
-
//
|
|
532
|
-
if (
|
|
631
|
+
// Use original syntax information if available
|
|
632
|
+
if (originalSyntax[key] === 'string') {
|
|
533
633
|
return `${key}="${value}"`;
|
|
534
|
-
} else if (
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
634
|
+
} else if (originalSyntax[key] === 'jsx') {
|
|
635
|
+
// Check if the JSX expression is actually a string literal (e.g., 'a' or "a")
|
|
636
|
+
if (
|
|
637
|
+
typeof value === 'string' &&
|
|
638
|
+
((value.startsWith("'") &&
|
|
639
|
+
value.endsWith("'") &&
|
|
640
|
+
value.length > 1) ||
|
|
641
|
+
(value.startsWith('"') &&
|
|
642
|
+
value.endsWith('"') &&
|
|
643
|
+
value.length > 1))
|
|
644
|
+
) {
|
|
645
|
+
// It's a string literal in JSX, convert to string prop
|
|
646
|
+
const stringValue = value.slice(1, -1); // Remove quotes
|
|
647
|
+
return `${key}="${stringValue}"`;
|
|
648
|
+
} else {
|
|
649
|
+
// It's a real JSX expression, keep as is
|
|
650
|
+
return `${key}={${value}}`;
|
|
651
|
+
}
|
|
652
|
+
} else if (originalSyntax[key] === 'boolean') {
|
|
653
|
+
return value ? key : '';
|
|
541
654
|
} else {
|
|
542
|
-
|
|
655
|
+
// Fallback logic for when originalSyntax is not available
|
|
656
|
+
if (typeof value === 'string' && !value.includes('{')) {
|
|
657
|
+
return `${key}="${value}"`;
|
|
658
|
+
} else if (
|
|
659
|
+
typeof value === 'string' &&
|
|
660
|
+
value.startsWith('{') &&
|
|
661
|
+
value.endsWith('}')
|
|
662
|
+
) {
|
|
663
|
+
// Already a JSX object, don't add extra braces
|
|
664
|
+
return `${key}={${value}}`;
|
|
665
|
+
} else {
|
|
666
|
+
return `${key}={${value}}`;
|
|
667
|
+
}
|
|
543
668
|
}
|
|
544
669
|
})
|
|
670
|
+
.filter(prop => prop.length > 0) // Remove empty props (like false booleans)
|
|
545
671
|
.join(' ')
|
|
546
672
|
);
|
|
547
673
|
}
|
|
@@ -551,40 +677,113 @@ function updateImports(content) {
|
|
|
551
677
|
let updatedContent = content;
|
|
552
678
|
let changes = 0;
|
|
553
679
|
|
|
554
|
-
//
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
680
|
+
// Handle CSS imports separately - these should stay with the main package
|
|
681
|
+
const cssImportPattern = /from\s+['"`]@entur\/typography\/styles['"`]/g;
|
|
682
|
+
if (cssImportPattern.test(content)) {
|
|
683
|
+
// CSS imports should remain unchanged as they're still in the main package
|
|
684
|
+
// No changes needed for CSS imports
|
|
685
|
+
}
|
|
560
686
|
|
|
561
|
-
//
|
|
562
|
-
// Find all import statements from @entur/typography and update component names
|
|
687
|
+
// Handle component imports - only migrate if they contain components that need migration
|
|
563
688
|
const importRegex =
|
|
564
689
|
/import\s*{([^}]+)}\s*from\s*['"']@entur\/typography['"']/g;
|
|
565
690
|
|
|
566
691
|
updatedContent = updatedContent.replace(importRegex, (match, importList) => {
|
|
692
|
+
const components = importList
|
|
693
|
+
.split(',')
|
|
694
|
+
.map(comp => comp.trim())
|
|
695
|
+
.filter(comp => comp);
|
|
696
|
+
|
|
697
|
+
// Check if any of the imported components need migration
|
|
698
|
+
// Need to check both the full import (e.g., "Link as Li") and just the component name (e.g., "Link")
|
|
699
|
+
const needsMigration = components.some(comp => {
|
|
700
|
+
// Extract the actual component name from aliased imports
|
|
701
|
+
const componentName = comp.includes(' as ')
|
|
702
|
+
? comp.split(' as ')[0].trim()
|
|
703
|
+
: comp;
|
|
704
|
+
return Object.keys(COMPONENT_MAPPING).includes(componentName);
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
if (!needsMigration) {
|
|
708
|
+
// No migration needed, keep the import as is
|
|
709
|
+
return match;
|
|
710
|
+
}
|
|
711
|
+
|
|
567
712
|
let updatedImportList = importList;
|
|
568
713
|
let hasChanges = false;
|
|
569
714
|
const uniqueComponents = new Set();
|
|
715
|
+
const processedComponents = new Set(); // Track which components we've already processed
|
|
716
|
+
|
|
717
|
+
// First, collect all existing components that should be preserved
|
|
718
|
+
const existingComponents = components.filter(comp => {
|
|
719
|
+
// Extract the actual component name from aliased imports
|
|
720
|
+
const componentName = comp.includes(' as ')
|
|
721
|
+
? comp.split(' as ')[0].trim()
|
|
722
|
+
: comp;
|
|
723
|
+
|
|
724
|
+
// Keep components that are:
|
|
725
|
+
// 1. Not in the migration mapping (old components), OR
|
|
726
|
+
// 2. Are the target components (new beta components)
|
|
727
|
+
const isOldComponent =
|
|
728
|
+
Object.keys(COMPONENT_MAPPING).includes(componentName);
|
|
729
|
+
const isTargetComponent = Object.values(COMPONENT_MAPPING).some(
|
|
730
|
+
mapping => mapping.component === componentName,
|
|
731
|
+
);
|
|
570
732
|
|
|
571
|
-
|
|
733
|
+
return !isOldComponent || isTargetComponent;
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
// Then, update components that need migration
|
|
572
737
|
Object.entries(COMPONENT_MAPPING).forEach(([oldComponent, mapping]) => {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
738
|
+
// Check if this old component exists in any form (aliased or not)
|
|
739
|
+
const hasComponent = components.some(comp => {
|
|
740
|
+
const componentName = comp.includes(' as ')
|
|
741
|
+
? comp.split(' as ')[0].trim()
|
|
742
|
+
: comp;
|
|
743
|
+
return componentName === oldComponent;
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
if (hasComponent && !processedComponents.has(oldComponent)) {
|
|
747
|
+
// Replace the old component with the new one, preserving aliases
|
|
748
|
+
const componentRegex = new RegExp(`\\b${oldComponent}\\b`, 'g');
|
|
749
|
+
if (componentRegex.test(updatedImportList)) {
|
|
750
|
+
updatedImportList = updatedImportList.replace(
|
|
751
|
+
componentRegex,
|
|
752
|
+
mapping.component,
|
|
753
|
+
);
|
|
754
|
+
|
|
755
|
+
// Only add to uniqueComponents if the component isn't already present in aliased form
|
|
756
|
+
const componentAlreadyPresent = components.some(comp => {
|
|
757
|
+
const componentName = comp.includes(' as ')
|
|
758
|
+
? comp.split(' as ')[0].trim()
|
|
759
|
+
: comp;
|
|
760
|
+
return componentName === mapping.component;
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
if (!componentAlreadyPresent) {
|
|
764
|
+
uniqueComponents.add(mapping.component);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
processedComponents.add(oldComponent);
|
|
768
|
+
hasChanges = true;
|
|
769
|
+
}
|
|
581
770
|
}
|
|
582
771
|
});
|
|
583
772
|
|
|
584
773
|
if (hasChanges) {
|
|
585
774
|
changes++;
|
|
586
|
-
//
|
|
587
|
-
const
|
|
775
|
+
// Combine existing components with migrated components
|
|
776
|
+
const allComponents = [
|
|
777
|
+
...existingComponents,
|
|
778
|
+
...Array.from(uniqueComponents),
|
|
779
|
+
];
|
|
780
|
+
|
|
781
|
+
// Filter out any empty components and deduplicate
|
|
782
|
+
const finalComponents = allComponents
|
|
783
|
+
.filter(comp => comp && comp.trim())
|
|
784
|
+
.filter((comp, index, arr) => arr.indexOf(comp) === index); // Remove duplicates
|
|
785
|
+
|
|
786
|
+
const finalImportList = finalComponents.join(', ');
|
|
588
787
|
return `import {${finalImportList}} from '${BETA_IMPORT}'`;
|
|
589
788
|
}
|
|
590
789
|
|
|
@@ -610,8 +809,12 @@ function updateComponents(content) {
|
|
|
610
809
|
changes++;
|
|
611
810
|
|
|
612
811
|
// Parse existing props
|
|
613
|
-
const {
|
|
614
|
-
|
|
812
|
+
const {
|
|
813
|
+
props: existingProps,
|
|
814
|
+
warnings: parseWarnings,
|
|
815
|
+
spreadProps,
|
|
816
|
+
originalSyntax,
|
|
817
|
+
} = parseJSXProps(propsString);
|
|
615
818
|
warnings.push(...parseWarnings);
|
|
616
819
|
|
|
617
820
|
// Migrate props
|
|
@@ -631,8 +834,46 @@ function updateComponents(content) {
|
|
|
631
834
|
|
|
632
835
|
// Handle Heading components
|
|
633
836
|
if (mapping.component === 'Heading') {
|
|
634
|
-
|
|
635
|
-
const
|
|
837
|
+
// Preserve existing 'as' prop if it exists, otherwise use mapping default
|
|
838
|
+
const asValue = existingProps.as || mapping.as;
|
|
839
|
+
// Preserve existing 'variant' prop if it exists, otherwise use mapping default
|
|
840
|
+
const variantValue = existingProps.variant || mapping.variant;
|
|
841
|
+
|
|
842
|
+
// Remove as and variant from props since we'll add them separately
|
|
843
|
+
delete newProps.as;
|
|
844
|
+
delete newProps.variant;
|
|
845
|
+
|
|
846
|
+
// Create props object with as and variant, preserving original syntax
|
|
847
|
+
const headingProps = {
|
|
848
|
+
as: asValue,
|
|
849
|
+
variant: variantValue,
|
|
850
|
+
...newProps,
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// Create original syntax object for as and variant
|
|
854
|
+
const headingOriginalSyntax = {
|
|
855
|
+
as: originalSyntax.as || 'string',
|
|
856
|
+
variant: originalSyntax.variant || 'string',
|
|
857
|
+
...originalSyntax,
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
const propsString = propsToString(
|
|
861
|
+
headingProps,
|
|
862
|
+
headingOriginalSyntax,
|
|
863
|
+
);
|
|
864
|
+
const spreadPropsString =
|
|
865
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
866
|
+
return `<Heading${propsString}${spreadPropsString}>`;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// Handle Label components with special case for htmlFor prop
|
|
870
|
+
if (oldComponent === 'Label' && mapping.component === 'Text') {
|
|
871
|
+
// If htmlFor prop exists, add as="label" to ensure proper semantic HTML
|
|
872
|
+
// Otherwise, use existing as prop or default to undefined (no as prop)
|
|
873
|
+
const asValue = existingProps.htmlFor
|
|
874
|
+
? 'label'
|
|
875
|
+
: existingProps.as || undefined;
|
|
876
|
+
const variantValue = existingProps.variant || mapping.variant;
|
|
636
877
|
|
|
637
878
|
// Remove as and variant from props since we'll add them separately
|
|
638
879
|
delete newProps.as;
|
|
@@ -646,8 +887,13 @@ function updateComponents(content) {
|
|
|
646
887
|
}
|
|
647
888
|
Object.assign(orderedProps, newProps);
|
|
648
889
|
|
|
649
|
-
const propsString = propsToString(orderedProps);
|
|
650
|
-
|
|
890
|
+
const propsString = propsToString(orderedProps, originalSyntax);
|
|
891
|
+
const spreadPropsString =
|
|
892
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
893
|
+
|
|
894
|
+
// Only add as prop if it has a value
|
|
895
|
+
const asProp = asValue ? ` as="${asValue}"` : '';
|
|
896
|
+
return `<Text${asProp} variant="${variantValue}"${propsString}${spreadPropsString}>`;
|
|
651
897
|
}
|
|
652
898
|
|
|
653
899
|
// Handle other components
|
|
@@ -669,8 +915,10 @@ function updateComponents(content) {
|
|
|
669
915
|
});
|
|
670
916
|
Object.assign(finalProps, newProps);
|
|
671
917
|
|
|
672
|
-
const otherPropsString = propsToString(finalProps);
|
|
673
|
-
|
|
918
|
+
const otherPropsString = propsToString(finalProps, originalSyntax);
|
|
919
|
+
const spreadPropsString =
|
|
920
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
921
|
+
return `<${componentName}${otherPropsString}${spreadPropsString}>`;
|
|
674
922
|
},
|
|
675
923
|
);
|
|
676
924
|
|
|
@@ -698,15 +946,33 @@ function updateComponents(content) {
|
|
|
698
946
|
* @returns {string[]} Array of matching file paths
|
|
699
947
|
*/
|
|
700
948
|
function findFiles(pattern) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
949
|
+
const allFiles = [];
|
|
950
|
+
|
|
951
|
+
// Process directory patterns
|
|
952
|
+
const directoryPatterns = ALLOWED_DIRECTORIES.filter(dir =>
|
|
953
|
+
dir.includes('**'),
|
|
954
|
+
);
|
|
955
|
+
const filePatterns = ALLOWED_DIRECTORIES.filter(dir => !dir.includes('**'));
|
|
956
|
+
|
|
957
|
+
// Handle directory patterns (e.g., src/**, app/**)
|
|
958
|
+
if (directoryPatterns.length > 0) {
|
|
959
|
+
const combinedDirPattern = `{${directoryPatterns.join(',')}}/${pattern}`;
|
|
960
|
+
const dirFiles = glob.sync(combinedDirPattern, {
|
|
961
|
+
ignore: BLOCKED_DIRECTORIES,
|
|
962
|
+
nodir: true,
|
|
963
|
+
absolute: false,
|
|
964
|
+
});
|
|
965
|
+
allFiles.push(...dirFiles);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// Handle file patterns (e.g., *.jsx, *.tsx)
|
|
969
|
+
filePatterns.forEach(filePattern => {
|
|
970
|
+
const files = glob.sync(filePattern, {
|
|
971
|
+
ignore: BLOCKED_DIRECTORIES,
|
|
972
|
+
nodir: true,
|
|
973
|
+
absolute: false,
|
|
974
|
+
});
|
|
975
|
+
allFiles.push(...files);
|
|
710
976
|
});
|
|
711
977
|
|
|
712
978
|
// Use Set for efficient deduplication and filtering
|
|
@@ -727,37 +993,29 @@ function findFiles(pattern) {
|
|
|
727
993
|
return uniqueFiles;
|
|
728
994
|
}
|
|
729
995
|
|
|
730
|
-
function updateImportsAndComponents(content
|
|
996
|
+
function updateImportsAndComponents(content) {
|
|
731
997
|
let updatedContent = content;
|
|
732
998
|
let changes = 0;
|
|
733
999
|
let warnings = [];
|
|
734
1000
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
changes
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
content: finalContent,
|
|
747
|
-
changes: componentChanges,
|
|
748
|
-
warnings: componentWarnings,
|
|
749
|
-
} = updateComponents(newContent);
|
|
750
|
-
updatedContent = finalContent;
|
|
751
|
-
changes = importChanges + componentChanges;
|
|
752
|
-
warnings = componentWarnings;
|
|
753
|
-
}
|
|
1001
|
+
// Update both imports and components
|
|
1002
|
+
const { content: newContent, changes: importChanges } =
|
|
1003
|
+
updateImports(content);
|
|
1004
|
+
const {
|
|
1005
|
+
content: finalContent,
|
|
1006
|
+
changes: componentChanges,
|
|
1007
|
+
warnings: componentWarnings,
|
|
1008
|
+
} = updateComponents(newContent);
|
|
1009
|
+
updatedContent = finalContent;
|
|
1010
|
+
changes = importChanges + componentChanges;
|
|
1011
|
+
warnings = componentWarnings;
|
|
754
1012
|
|
|
755
1013
|
return { content: updatedContent, changes, warnings };
|
|
756
1014
|
}
|
|
757
1015
|
|
|
758
|
-
function generateMigrationReport(files,
|
|
1016
|
+
function generateMigrationReport(files, isDryRun = false) {
|
|
759
1017
|
const report = {
|
|
760
|
-
strategy,
|
|
1018
|
+
strategy: 'complete',
|
|
761
1019
|
totalFiles: files.length,
|
|
762
1020
|
migratedFiles: 0,
|
|
763
1021
|
totalChanges: 0,
|
|
@@ -778,7 +1036,7 @@ function generateMigrationReport(files, strategy, isDryRun = false) {
|
|
|
778
1036
|
content: updatedContent,
|
|
779
1037
|
changes,
|
|
780
1038
|
warnings,
|
|
781
|
-
} = updateImportsAndComponents(content
|
|
1039
|
+
} = updateImportsAndComponents(content);
|
|
782
1040
|
|
|
783
1041
|
// Combine migration warnings with file analysis warnings
|
|
784
1042
|
const allWarnings = [...warnings, ...fileAnalysis.warnings];
|
|
@@ -1008,23 +1266,13 @@ function printReport(report) {
|
|
|
1008
1266
|
}
|
|
1009
1267
|
}
|
|
1010
1268
|
|
|
1011
|
-
function showNextSteps(
|
|
1269
|
+
function showNextSteps() {
|
|
1012
1270
|
console.log('\n📝 Next Steps');
|
|
1013
1271
|
console.log('=============');
|
|
1014
1272
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
Object.entries(COMPONENT_MAPPING).forEach(([old, new_]) => {
|
|
1019
|
-
console.log(` ${old} → ${new_}`);
|
|
1020
|
-
});
|
|
1021
|
-
console.log('3. 🧪 Test your application');
|
|
1022
|
-
console.log('4. 📚 Read the migration guide on our website');
|
|
1023
|
-
} else if (strategy === 'complete') {
|
|
1024
|
-
console.log('1. 🧪 Test your application thoroughly');
|
|
1025
|
-
console.log('2. 🔄 Review and adjust any component props if needed');
|
|
1026
|
-
console.log('3. 📚 Read the migration guide on our website');
|
|
1027
|
-
}
|
|
1273
|
+
console.log('1. 🧪 Test your application thoroughly');
|
|
1274
|
+
console.log('2. 🔄 Review and adjust any component props if needed');
|
|
1275
|
+
console.log('3. 📚 Read the migration guide on our website');
|
|
1028
1276
|
|
|
1029
1277
|
console.log('\n⚠️ Important Notes:');
|
|
1030
1278
|
console.log('- Check warnings above for potential issues');
|
|
@@ -1032,7 +1280,7 @@ function showNextSteps(strategy) {
|
|
|
1032
1280
|
console.log('- Test thoroughly, especially components with custom styling');
|
|
1033
1281
|
}
|
|
1034
1282
|
|
|
1035
|
-
function main() {
|
|
1283
|
+
async function main() {
|
|
1036
1284
|
// Show help if requested
|
|
1037
1285
|
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
1038
1286
|
console.log('🎨 Typography Migration Script');
|
|
@@ -1053,36 +1301,24 @@ function main() {
|
|
|
1053
1301
|
console.log(
|
|
1054
1302
|
' --dry-run Show what would be changed without modifying files',
|
|
1055
1303
|
);
|
|
1056
|
-
console.log(
|
|
1057
|
-
' --import-only Import-only migration: update import paths only',
|
|
1058
|
-
);
|
|
1059
|
-
|
|
1060
1304
|
console.log(' --help, -h Show this help message');
|
|
1061
1305
|
console.log('');
|
|
1062
|
-
console.log('Migration
|
|
1063
|
-
console.log(' 🚀 Complete Mode
|
|
1306
|
+
console.log('Migration Mode:');
|
|
1307
|
+
console.log(' 🚀 Complete Mode: Updates everything');
|
|
1064
1308
|
console.log(' - Replaces old components with beta components');
|
|
1065
|
-
console.log(' -
|
|
1309
|
+
console.log(' - Heading1-6 → Heading with as/variant props');
|
|
1310
|
+
console.log(' - Text components → Text with variant props');
|
|
1311
|
+
console.log(' - All typography components migrate to beta versions');
|
|
1312
|
+
console.log(' - Import paths change to @entur/typography/beta');
|
|
1313
|
+
console.log(' - May require prop/styling updates (margin → spacing)');
|
|
1066
1314
|
console.log(' - Test thoroughly after migration');
|
|
1067
1315
|
console.log('');
|
|
1068
|
-
console.log(
|
|
1069
|
-
' 📝 Import-Only Mode (--import-only): Only updates import paths',
|
|
1070
|
-
);
|
|
1071
|
-
console.log(' - Keeps your existing component usage unchanged');
|
|
1072
|
-
console.log(' - Minimal risk, gradual migration');
|
|
1073
|
-
console.log('');
|
|
1074
1316
|
console.log('Examples:');
|
|
1075
1317
|
console.log(' # See what would be changed');
|
|
1076
1318
|
console.log(' npx @entur/typography@latest migrate --dry-run');
|
|
1077
1319
|
console.log('');
|
|
1078
1320
|
console.log(' # Complete migration: update everything (default)');
|
|
1079
1321
|
console.log(' npx @entur/typography@latest migrate');
|
|
1080
|
-
console.log('');
|
|
1081
|
-
console.log(' # Import-only migration: update import paths only');
|
|
1082
|
-
console.log(' npx @entur/typography@latest migrate --import-only');
|
|
1083
|
-
console.log('');
|
|
1084
|
-
|
|
1085
|
-
console.log('');
|
|
1086
1322
|
|
|
1087
1323
|
console.log('Environment Variables:');
|
|
1088
1324
|
console.log(
|
|
@@ -1098,7 +1334,7 @@ function main() {
|
|
|
1098
1334
|
console.log(' Add/remove folder patterns between the 👇 and 👆 markers');
|
|
1099
1335
|
console.log(' Examples: "src/**", "app/**", "packages/my-app/**"');
|
|
1100
1336
|
console.log('');
|
|
1101
|
-
console.log(' Option 2: Set environment variable
|
|
1337
|
+
console.log(' Option 2: Set environment variable');
|
|
1102
1338
|
console.log(
|
|
1103
1339
|
' export TYPOGRAPHY_MIGRATION_DIRS="src/**,app/**,components/**"',
|
|
1104
1340
|
);
|
|
@@ -1166,47 +1402,48 @@ function main() {
|
|
|
1166
1402
|
|
|
1167
1403
|
// Parse command line options
|
|
1168
1404
|
const isDryRun = process.argv.includes('--dry-run');
|
|
1169
|
-
const isImportOnly = process.argv.includes('--import-only');
|
|
1170
1405
|
|
|
1171
1406
|
if (isDryRun) {
|
|
1172
1407
|
console.log('🔍 DRY RUN MODE: No files will be modified');
|
|
1173
1408
|
console.log('');
|
|
1174
1409
|
}
|
|
1175
1410
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1411
|
+
console.log('🚀 COMPLETE MIGRATION: Updating imports + component usage');
|
|
1412
|
+
console.log('⚠️ WARNING: This will modify your component usage!');
|
|
1413
|
+
console.log(' - Old components will be replaced with beta components');
|
|
1414
|
+
console.log(' - Import paths will change to @entur/typography/beta');
|
|
1415
|
+
console.log(
|
|
1416
|
+
' - Link → Link, Blockquote → Blockquote, Lists → List components (from beta)',
|
|
1417
|
+
);
|
|
1418
|
+
console.log(
|
|
1419
|
+
' - List components → UnorderedList, NumberedList, ListItem (from beta)',
|
|
1420
|
+
);
|
|
1421
|
+
console.log(' - Props may change (margin → spacing)');
|
|
1422
|
+
console.log(' - Test thoroughly after migration');
|
|
1188
1423
|
|
|
1189
1424
|
console.log('');
|
|
1190
1425
|
|
|
1191
1426
|
// Perform migration
|
|
1192
|
-
const report = generateMigrationReport(
|
|
1193
|
-
allFiles,
|
|
1194
|
-
isImportOnly ? 'import-only' : 'complete',
|
|
1195
|
-
isDryRun,
|
|
1196
|
-
);
|
|
1427
|
+
const report = generateMigrationReport(allFiles, isDryRun);
|
|
1197
1428
|
printReport(report);
|
|
1198
|
-
showNextSteps(
|
|
1429
|
+
showNextSteps();
|
|
1199
1430
|
|
|
1200
1431
|
console.log('\n🎯 Migration complete!');
|
|
1201
1432
|
}
|
|
1202
1433
|
|
|
1203
|
-
if
|
|
1204
|
-
|
|
1434
|
+
// Check if this module is being run directly
|
|
1435
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
1436
|
+
main().catch(error => {
|
|
1437
|
+
console.error('❌ Migration failed:', error);
|
|
1438
|
+
process.exit(1);
|
|
1439
|
+
});
|
|
1205
1440
|
}
|
|
1206
1441
|
|
|
1207
|
-
|
|
1442
|
+
export {
|
|
1208
1443
|
updateImportsAndComponents,
|
|
1209
1444
|
generateMigrationReport,
|
|
1210
1445
|
COMPONENT_MAPPING,
|
|
1211
1446
|
PROPS_MAPPING,
|
|
1447
|
+
parseJSXProps,
|
|
1448
|
+
propsToString,
|
|
1212
1449
|
};
|