@entur/typography 1.10.0-beta.9 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +430 -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,31 +57,44 @@
|
|
|
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.',
|
|
59
76
|
);
|
|
60
77
|
console.error('');
|
|
61
|
-
console.error('Please install it:');
|
|
78
|
+
console.error('Please install it first:');
|
|
62
79
|
console.error(' npm install glob');
|
|
63
80
|
console.error(' yarn add glob');
|
|
81
|
+
console.error(' pnpm add glob');
|
|
64
82
|
console.error('');
|
|
65
|
-
console.error('
|
|
83
|
+
console.error('Then run the migration:');
|
|
66
84
|
console.error(' npx @entur/typography@latest migrate');
|
|
85
|
+
console.error(' yarn dlx @entur/typography@latest migrate');
|
|
86
|
+
console.error('');
|
|
87
|
+
console.error('📚 For more information, see:');
|
|
88
|
+
console.error(
|
|
89
|
+
' https://linje.entur.no/komponenter/ressurser/typography-migration',
|
|
90
|
+
);
|
|
67
91
|
console.error('');
|
|
68
92
|
process.exit(1);
|
|
69
93
|
}
|
|
70
94
|
|
|
71
95
|
// Configuration
|
|
72
96
|
const OLD_IMPORT = '@entur/typography';
|
|
73
|
-
const BETA_IMPORT = '@entur/typography';
|
|
97
|
+
const BETA_IMPORT = '@entur/typography/beta';
|
|
74
98
|
|
|
75
99
|
// Enhanced warning detection patterns - only truly problematic patterns
|
|
76
100
|
const PROBLEMATIC_PATTERNS = {
|
|
@@ -123,6 +147,7 @@ const MIGRATION_FOLDERS = [
|
|
|
123
147
|
'app/**',
|
|
124
148
|
'apps/**',
|
|
125
149
|
'components/**',
|
|
150
|
+
'packages/**',
|
|
126
151
|
'pages/**',
|
|
127
152
|
'lib/**',
|
|
128
153
|
'utils/**',
|
|
@@ -342,13 +367,20 @@ const COMPONENT_MAPPING = {
|
|
|
342
367
|
Heading6: { component: 'Heading', as: 'h6', variant: 'section-2' },
|
|
343
368
|
Paragraph: { component: 'Text', variant: 'paragraph' },
|
|
344
369
|
LeadParagraph: { component: 'Text', variant: 'leading' },
|
|
345
|
-
SmallText: { component: 'Text', variant: 'subparagraph'
|
|
346
|
-
StrongText: { component: 'Text',
|
|
347
|
-
SubLabel: { component: 'Text', variant: 'sublabel'
|
|
370
|
+
SmallText: { component: 'Text', variant: 'subparagraph' },
|
|
371
|
+
StrongText: { component: 'Text', as: 'strong', weight: 'bold' },
|
|
372
|
+
SubLabel: { component: 'Text', variant: 'sublabel' },
|
|
348
373
|
SubParagraph: { component: 'Text', variant: 'subparagraph' },
|
|
349
374
|
Label: { component: 'Text', variant: 'label' },
|
|
350
375
|
EmphasizedText: { component: 'Text', variant: 'emphasized' },
|
|
351
376
|
CodeText: { component: 'Text', variant: 'code-text' },
|
|
377
|
+
PreformattedText: { component: 'Text', variant: 'preformatted-text' },
|
|
378
|
+
Link: { component: 'Link' }, // Convert Link to beta Link
|
|
379
|
+
Blockquote: { component: 'Blockquote' }, // Convert Blockquote to beta Blockquote
|
|
380
|
+
BlockquoteFooter: { component: 'BlockquoteFooter' }, // Convert BlockquoteFooter to beta BlockquoteFooter
|
|
381
|
+
UnorderedList: { component: 'UnorderedList' },
|
|
382
|
+
NumberedList: { component: 'NumberedList' },
|
|
383
|
+
ListItem: { component: 'ListItem' },
|
|
352
384
|
};
|
|
353
385
|
|
|
354
386
|
// Props mapping for migration
|
|
@@ -357,17 +389,43 @@ const PROPS_MAPPING = {
|
|
|
357
389
|
};
|
|
358
390
|
|
|
359
391
|
// Spacing value mapping from old margin to new spacing
|
|
392
|
+
// Based on the actual CSS classes in src/beta/styles.scss
|
|
393
|
+
// and the old margin prop values: "top" | "bottom" | "both" | "none"
|
|
360
394
|
const SPACING_MAPPING = {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
395
|
+
// Old margin values mapped to new spacing values
|
|
396
|
+
none: 'none', // No spacing
|
|
397
|
+
top: 'md-top', // Top margin only (medium size)
|
|
398
|
+
bottom: 'md-bottom', // Bottom margin only (medium size)
|
|
399
|
+
both: 'md', // Both top and bottom margins (medium size)
|
|
400
|
+
|
|
401
|
+
// Additional spacing values for more granular control
|
|
402
|
+
// These weren't in the old margin prop but are available in new spacing
|
|
403
|
+
left: 'md-left', // Left margin (medium size)
|
|
404
|
+
right: 'md-right', // Right margin (medium size)
|
|
405
|
+
|
|
406
|
+
// Size-based spacing (applies to both top and bottom)
|
|
366
407
|
xs: 'xs',
|
|
367
408
|
sm: 'sm',
|
|
368
409
|
md: 'md',
|
|
369
410
|
lg: 'lg',
|
|
370
411
|
xl: 'xl',
|
|
412
|
+
|
|
413
|
+
// Specific directional spacing with sizes
|
|
414
|
+
'xs-top': 'xs-top',
|
|
415
|
+
'xs-bottom': 'xs-bottom',
|
|
416
|
+
'sm-top': 'sm-top',
|
|
417
|
+
'sm-bottom': 'sm-bottom',
|
|
418
|
+
'md-top': 'md-top',
|
|
419
|
+
'md-bottom': 'md-bottom',
|
|
420
|
+
'lg-top': 'lg-top',
|
|
421
|
+
'lg-bottom': 'lg-bottom',
|
|
422
|
+
'xl-top': 'xl-top',
|
|
423
|
+
'xl-bottom': 'xl-bottom',
|
|
424
|
+
|
|
425
|
+
// Extra small variants
|
|
426
|
+
xs2: 'xs2',
|
|
427
|
+
'xs2-top': 'xs2-top',
|
|
428
|
+
'xs2-bottom': 'xs2-bottom',
|
|
371
429
|
};
|
|
372
430
|
|
|
373
431
|
// Import patterns to handle
|
|
@@ -376,35 +434,40 @@ const IMPORT_PATTERNS = [
|
|
|
376
434
|
/from\s+['"`]@entur\/typography\/dist['"`]/g,
|
|
377
435
|
/from\s+['"`]@entur\/typography\/dist\/index['"`]/g,
|
|
378
436
|
/from\s+['"`]@entur\/typography\/dist\/styles\.css['"`]/g,
|
|
437
|
+
/from\s+['"`]@entur\/typography\/styles['"`]/g,
|
|
379
438
|
];
|
|
380
439
|
|
|
381
440
|
// Parse JSX props more robustly
|
|
382
441
|
function parseJSXProps(propsString) {
|
|
383
442
|
if (!propsString || !propsString.trim()) {
|
|
384
|
-
return { props: {}, warnings: [] };
|
|
443
|
+
return { props: {}, warnings: [], spreadProps: [] };
|
|
385
444
|
}
|
|
386
445
|
|
|
387
446
|
const props = {};
|
|
388
447
|
const warnings = [];
|
|
389
|
-
const
|
|
390
|
-
|
|
448
|
+
const spreadProps = []; // Track spread props separately
|
|
449
|
+
const originalSyntax = {}; // Track original JSX syntax for each prop
|
|
391
450
|
|
|
392
451
|
try {
|
|
393
452
|
// Parse props manually to handle complex cases
|
|
394
453
|
let remaining = propsString.trim();
|
|
395
|
-
let lastRemainingLength = remaining.length;
|
|
396
454
|
|
|
397
|
-
|
|
398
|
-
|
|
455
|
+
// First, extract all spread props
|
|
456
|
+
const spreadRegex = /\.\.\.\{?(\w+)\}?/g;
|
|
457
|
+
let spreadMatch;
|
|
458
|
+
while ((spreadMatch = spreadRegex.exec(remaining)) !== null) {
|
|
459
|
+
spreadProps.push(spreadMatch[1]);
|
|
460
|
+
}
|
|
399
461
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
462
|
+
// Remove spread props from the string to parse regular props
|
|
463
|
+
remaining = remaining.replace(/\.\.\.\{?(\w+)\}?/g, '');
|
|
464
|
+
|
|
465
|
+
// Now parse regular props
|
|
466
|
+
while (remaining.trim().length > 0) {
|
|
467
|
+
// Skip whitespace
|
|
468
|
+
remaining = remaining.replace(/^\s+/, '');
|
|
406
469
|
|
|
407
|
-
// Match prop name
|
|
470
|
+
// Match prop name
|
|
408
471
|
const nameMatch = remaining.match(/^(\w+)=/);
|
|
409
472
|
if (!nameMatch) break;
|
|
410
473
|
|
|
@@ -414,7 +477,7 @@ function parseJSXProps(propsString) {
|
|
|
414
477
|
|
|
415
478
|
// Match prop value
|
|
416
479
|
if (remaining.startsWith('"') || remaining.startsWith("'")) {
|
|
417
|
-
// String value
|
|
480
|
+
// String value
|
|
418
481
|
const quote = remaining[0];
|
|
419
482
|
const endQuoteIndex = remaining.indexOf(quote, 1);
|
|
420
483
|
if (endQuoteIndex === -1) {
|
|
@@ -424,14 +487,14 @@ function parseJSXProps(propsString) {
|
|
|
424
487
|
|
|
425
488
|
const propValue = remaining.substring(1, endQuoteIndex);
|
|
426
489
|
props[propName] = propValue;
|
|
490
|
+
originalSyntax[propName] = 'string'; // Mark as string literal
|
|
427
491
|
remaining = remaining.substring(endQuoteIndex + 1);
|
|
428
492
|
} else if (remaining.startsWith('{')) {
|
|
429
|
-
// Object value - find matching closing brace
|
|
493
|
+
// Object value - find matching closing brace
|
|
430
494
|
let braceCount = 0;
|
|
431
495
|
let endIndex = -1;
|
|
432
|
-
const maxSearchLength = Math.min(remaining.length, 1000); // Limit search length
|
|
433
496
|
|
|
434
|
-
for (let i = 0; i <
|
|
497
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
435
498
|
if (remaining[i] === '{') braceCount++;
|
|
436
499
|
if (remaining[i] === '}') {
|
|
437
500
|
braceCount--;
|
|
@@ -449,25 +512,23 @@ function parseJSXProps(propsString) {
|
|
|
449
512
|
|
|
450
513
|
const propValue = remaining.substring(1, endIndex);
|
|
451
514
|
props[propName] = propValue;
|
|
515
|
+
originalSyntax[propName] = 'jsx'; // Mark as JSX expression
|
|
452
516
|
remaining = remaining.substring(endIndex + 1);
|
|
453
517
|
} else {
|
|
454
|
-
// Boolean prop
|
|
518
|
+
// Boolean prop
|
|
455
519
|
props[propName] = true;
|
|
520
|
+
originalSyntax[propName] = 'boolean'; // Mark as boolean
|
|
456
521
|
break;
|
|
457
522
|
}
|
|
458
523
|
|
|
459
|
-
// Skip whitespace
|
|
524
|
+
// Skip whitespace
|
|
460
525
|
remaining = remaining.replace(/^\s+/, '');
|
|
461
526
|
}
|
|
462
|
-
|
|
463
|
-
if (iterationCount >= MAX_ITERATIONS) {
|
|
464
|
-
warnings.push(`Maximum parsing iterations (${MAX_ITERATIONS}) reached`);
|
|
465
|
-
}
|
|
466
527
|
} catch (error) {
|
|
467
528
|
warnings.push(`Failed to parse props: ${error.message}`);
|
|
468
529
|
}
|
|
469
530
|
|
|
470
|
-
return { props, warnings };
|
|
531
|
+
return { props, warnings, spreadProps, originalSyntax };
|
|
471
532
|
}
|
|
472
533
|
|
|
473
534
|
// Migrate props from old to new format
|
|
@@ -485,11 +546,12 @@ function migrateProps(props, oldComponent) {
|
|
|
485
546
|
`Migrated 'margin="${props.margin}"' to 'spacing="${newSpacing}"'`,
|
|
486
547
|
);
|
|
487
548
|
} else {
|
|
488
|
-
// Unknown margin value -
|
|
489
|
-
|
|
549
|
+
// Unknown margin value - suggest alternatives
|
|
550
|
+
const suggestions = getSpacingSuggestions(props.margin);
|
|
551
|
+
migratedProps.spacing = props.margin; // Keep original value for now
|
|
490
552
|
delete migratedProps.margin;
|
|
491
553
|
warnings.push(
|
|
492
|
-
`Migrated 'margin="${props.margin}"' to 'spacing="${props.margin}"' (unknown value
|
|
554
|
+
`Migrated 'margin="${props.margin}"' to 'spacing="${props.margin}"' (unknown value). ${suggestions}`,
|
|
493
555
|
);
|
|
494
556
|
}
|
|
495
557
|
}
|
|
@@ -516,8 +578,55 @@ function migrateProps(props, oldComponent) {
|
|
|
516
578
|
return { props: migratedProps, warnings };
|
|
517
579
|
}
|
|
518
580
|
|
|
581
|
+
// Helper function to suggest spacing alternatives for unknown margin values
|
|
582
|
+
function getSpacingSuggestions(unknownMargin) {
|
|
583
|
+
const suggestions = [];
|
|
584
|
+
|
|
585
|
+
// Check if it might be one of the old margin values
|
|
586
|
+
if (['top', 'bottom', 'both', 'none'].includes(unknownMargin)) {
|
|
587
|
+
suggestions.push(
|
|
588
|
+
`"${unknownMargin}" is a valid old margin value and will be migrated correctly.`,
|
|
589
|
+
);
|
|
590
|
+
return suggestions.join(' ');
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// Check if it might be a directional value
|
|
594
|
+
if (
|
|
595
|
+
unknownMargin.includes('top') ||
|
|
596
|
+
unknownMargin.includes('bottom') ||
|
|
597
|
+
unknownMargin.includes('left') ||
|
|
598
|
+
unknownMargin.includes('right')
|
|
599
|
+
) {
|
|
600
|
+
suggestions.push(
|
|
601
|
+
'Consider using directional spacing like "md-top", "sm-bottom", etc.',
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Check if it might be a size value
|
|
606
|
+
if (['xs', 'sm', 'md', 'lg', 'xl'].includes(unknownMargin)) {
|
|
607
|
+
suggestions.push(
|
|
608
|
+
'Consider using size-based spacing like "xs", "sm", "md", "lg", "xl".',
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Check if it might be a specific variant
|
|
613
|
+
if (unknownMargin.includes('xs2')) {
|
|
614
|
+
suggestions.push(
|
|
615
|
+
'Consider using "xs2", "xs2-top", or "xs2-bottom" for extra small spacing.',
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (suggestions.length === 0) {
|
|
620
|
+
suggestions.push(
|
|
621
|
+
'Old margin values: "none", "top", "bottom", "both". New spacing values: "xs", "sm", "md", "lg", "xl", and directional variants.',
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return suggestions.join(' ');
|
|
626
|
+
}
|
|
627
|
+
|
|
519
628
|
// Convert props object back to JSX string
|
|
520
|
-
function propsToString(props) {
|
|
629
|
+
function propsToString(props, originalSyntax = {}) {
|
|
521
630
|
if (!props || Object.keys(props).length === 0) {
|
|
522
631
|
return '';
|
|
523
632
|
}
|
|
@@ -526,20 +635,46 @@ function propsToString(props) {
|
|
|
526
635
|
' ' +
|
|
527
636
|
Object.entries(props)
|
|
528
637
|
.map(([key, value]) => {
|
|
529
|
-
//
|
|
530
|
-
if (
|
|
638
|
+
// Use original syntax information if available
|
|
639
|
+
if (originalSyntax[key] === 'string') {
|
|
531
640
|
return `${key}="${value}"`;
|
|
532
|
-
} else if (
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
641
|
+
} else if (originalSyntax[key] === 'jsx') {
|
|
642
|
+
// Check if the JSX expression is actually a string literal (e.g., 'a' or "a")
|
|
643
|
+
if (
|
|
644
|
+
typeof value === 'string' &&
|
|
645
|
+
((value.startsWith("'") &&
|
|
646
|
+
value.endsWith("'") &&
|
|
647
|
+
value.length > 1) ||
|
|
648
|
+
(value.startsWith('"') &&
|
|
649
|
+
value.endsWith('"') &&
|
|
650
|
+
value.length > 1))
|
|
651
|
+
) {
|
|
652
|
+
// It's a string literal in JSX, convert to string prop
|
|
653
|
+
const stringValue = value.slice(1, -1); // Remove quotes
|
|
654
|
+
return `${key}="${stringValue}"`;
|
|
655
|
+
} else {
|
|
656
|
+
// It's a real JSX expression, keep as is
|
|
657
|
+
return `${key}={${value}}`;
|
|
658
|
+
}
|
|
659
|
+
} else if (originalSyntax[key] === 'boolean') {
|
|
660
|
+
return value ? key : '';
|
|
539
661
|
} else {
|
|
540
|
-
|
|
662
|
+
// Fallback logic for when originalSyntax is not available
|
|
663
|
+
if (typeof value === 'string' && !value.includes('{')) {
|
|
664
|
+
return `${key}="${value}"`;
|
|
665
|
+
} else if (
|
|
666
|
+
typeof value === 'string' &&
|
|
667
|
+
value.startsWith('{') &&
|
|
668
|
+
value.endsWith('}')
|
|
669
|
+
) {
|
|
670
|
+
// Already a JSX object, don't add extra braces
|
|
671
|
+
return `${key}={${value}}`;
|
|
672
|
+
} else {
|
|
673
|
+
return `${key}={${value}}`;
|
|
674
|
+
}
|
|
541
675
|
}
|
|
542
676
|
})
|
|
677
|
+
.filter(prop => prop.length > 0) // Remove empty props (like false booleans)
|
|
543
678
|
.join(' ')
|
|
544
679
|
);
|
|
545
680
|
}
|
|
@@ -549,40 +684,113 @@ function updateImports(content) {
|
|
|
549
684
|
let updatedContent = content;
|
|
550
685
|
let changes = 0;
|
|
551
686
|
|
|
552
|
-
//
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
687
|
+
// Handle CSS imports separately - these should stay with the main package
|
|
688
|
+
const cssImportPattern = /from\s+['"`]@entur\/typography\/styles['"`]/g;
|
|
689
|
+
if (cssImportPattern.test(content)) {
|
|
690
|
+
// CSS imports should remain unchanged as they're still in the main package
|
|
691
|
+
// No changes needed for CSS imports
|
|
692
|
+
}
|
|
558
693
|
|
|
559
|
-
//
|
|
560
|
-
// Find all import statements from @entur/typography and update component names
|
|
694
|
+
// Handle component imports - only migrate if they contain components that need migration
|
|
561
695
|
const importRegex =
|
|
562
696
|
/import\s*{([^}]+)}\s*from\s*['"']@entur\/typography['"']/g;
|
|
563
697
|
|
|
564
698
|
updatedContent = updatedContent.replace(importRegex, (match, importList) => {
|
|
699
|
+
const components = importList
|
|
700
|
+
.split(',')
|
|
701
|
+
.map(comp => comp.trim())
|
|
702
|
+
.filter(comp => comp);
|
|
703
|
+
|
|
704
|
+
// Check if any of the imported components need migration
|
|
705
|
+
// Need to check both the full import (e.g., "Link as Li") and just the component name (e.g., "Link")
|
|
706
|
+
const needsMigration = components.some(comp => {
|
|
707
|
+
// Extract the actual component name from aliased imports
|
|
708
|
+
const componentName = comp.includes(' as ')
|
|
709
|
+
? comp.split(' as ')[0].trim()
|
|
710
|
+
: comp;
|
|
711
|
+
return Object.keys(COMPONENT_MAPPING).includes(componentName);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
if (!needsMigration) {
|
|
715
|
+
// No migration needed, keep the import as is
|
|
716
|
+
return match;
|
|
717
|
+
}
|
|
718
|
+
|
|
565
719
|
let updatedImportList = importList;
|
|
566
720
|
let hasChanges = false;
|
|
567
721
|
const uniqueComponents = new Set();
|
|
722
|
+
const processedComponents = new Set(); // Track which components we've already processed
|
|
723
|
+
|
|
724
|
+
// First, collect all existing components that should be preserved
|
|
725
|
+
const existingComponents = components.filter(comp => {
|
|
726
|
+
// Extract the actual component name from aliased imports
|
|
727
|
+
const componentName = comp.includes(' as ')
|
|
728
|
+
? comp.split(' as ')[0].trim()
|
|
729
|
+
: comp;
|
|
730
|
+
|
|
731
|
+
// Keep components that are:
|
|
732
|
+
// 1. Not in the migration mapping (old components), OR
|
|
733
|
+
// 2. Are the target components (new beta components)
|
|
734
|
+
const isOldComponent =
|
|
735
|
+
Object.keys(COMPONENT_MAPPING).includes(componentName);
|
|
736
|
+
const isTargetComponent = Object.values(COMPONENT_MAPPING).some(
|
|
737
|
+
mapping => mapping.component === componentName,
|
|
738
|
+
);
|
|
568
739
|
|
|
569
|
-
|
|
740
|
+
return !isOldComponent || isTargetComponent;
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
// Then, update components that need migration
|
|
570
744
|
Object.entries(COMPONENT_MAPPING).forEach(([oldComponent, mapping]) => {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
745
|
+
// Check if this old component exists in any form (aliased or not)
|
|
746
|
+
const hasComponent = components.some(comp => {
|
|
747
|
+
const componentName = comp.includes(' as ')
|
|
748
|
+
? comp.split(' as ')[0].trim()
|
|
749
|
+
: comp;
|
|
750
|
+
return componentName === oldComponent;
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
if (hasComponent && !processedComponents.has(oldComponent)) {
|
|
754
|
+
// Replace the old component with the new one, preserving aliases
|
|
755
|
+
const componentRegex = new RegExp(`\\b${oldComponent}\\b`, 'g');
|
|
756
|
+
if (componentRegex.test(updatedImportList)) {
|
|
757
|
+
updatedImportList = updatedImportList.replace(
|
|
758
|
+
componentRegex,
|
|
759
|
+
mapping.component,
|
|
760
|
+
);
|
|
761
|
+
|
|
762
|
+
// Only add to uniqueComponents if the component isn't already present in aliased form
|
|
763
|
+
const componentAlreadyPresent = components.some(comp => {
|
|
764
|
+
const componentName = comp.includes(' as ')
|
|
765
|
+
? comp.split(' as ')[0].trim()
|
|
766
|
+
: comp;
|
|
767
|
+
return componentName === mapping.component;
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
if (!componentAlreadyPresent) {
|
|
771
|
+
uniqueComponents.add(mapping.component);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
processedComponents.add(oldComponent);
|
|
775
|
+
hasChanges = true;
|
|
776
|
+
}
|
|
579
777
|
}
|
|
580
778
|
});
|
|
581
779
|
|
|
582
780
|
if (hasChanges) {
|
|
583
781
|
changes++;
|
|
584
|
-
//
|
|
585
|
-
const
|
|
782
|
+
// Combine existing components with migrated components
|
|
783
|
+
const allComponents = [
|
|
784
|
+
...existingComponents,
|
|
785
|
+
...Array.from(uniqueComponents),
|
|
786
|
+
];
|
|
787
|
+
|
|
788
|
+
// Filter out any empty components and deduplicate
|
|
789
|
+
const finalComponents = allComponents
|
|
790
|
+
.filter(comp => comp && comp.trim())
|
|
791
|
+
.filter((comp, index, arr) => arr.indexOf(comp) === index); // Remove duplicates
|
|
792
|
+
|
|
793
|
+
const finalImportList = finalComponents.join(', ');
|
|
586
794
|
return `import {${finalImportList}} from '${BETA_IMPORT}'`;
|
|
587
795
|
}
|
|
588
796
|
|
|
@@ -608,8 +816,12 @@ function updateComponents(content) {
|
|
|
608
816
|
changes++;
|
|
609
817
|
|
|
610
818
|
// Parse existing props
|
|
611
|
-
const {
|
|
612
|
-
|
|
819
|
+
const {
|
|
820
|
+
props: existingProps,
|
|
821
|
+
warnings: parseWarnings,
|
|
822
|
+
spreadProps,
|
|
823
|
+
originalSyntax,
|
|
824
|
+
} = parseJSXProps(propsString);
|
|
613
825
|
warnings.push(...parseWarnings);
|
|
614
826
|
|
|
615
827
|
// Migrate props
|
|
@@ -629,8 +841,46 @@ function updateComponents(content) {
|
|
|
629
841
|
|
|
630
842
|
// Handle Heading components
|
|
631
843
|
if (mapping.component === 'Heading') {
|
|
632
|
-
|
|
633
|
-
const
|
|
844
|
+
// Preserve existing 'as' prop if it exists, otherwise use mapping default
|
|
845
|
+
const asValue = existingProps.as || mapping.as;
|
|
846
|
+
// Preserve existing 'variant' prop if it exists, otherwise use mapping default
|
|
847
|
+
const variantValue = existingProps.variant || mapping.variant;
|
|
848
|
+
|
|
849
|
+
// Remove as and variant from props since we'll add them separately
|
|
850
|
+
delete newProps.as;
|
|
851
|
+
delete newProps.variant;
|
|
852
|
+
|
|
853
|
+
// Create props object with as and variant, preserving original syntax
|
|
854
|
+
const headingProps = {
|
|
855
|
+
as: asValue,
|
|
856
|
+
variant: variantValue,
|
|
857
|
+
...newProps,
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
// Create original syntax object for as and variant
|
|
861
|
+
const headingOriginalSyntax = {
|
|
862
|
+
as: originalSyntax.as || 'string',
|
|
863
|
+
variant: originalSyntax.variant || 'string',
|
|
864
|
+
...originalSyntax,
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
const propsString = propsToString(
|
|
868
|
+
headingProps,
|
|
869
|
+
headingOriginalSyntax,
|
|
870
|
+
);
|
|
871
|
+
const spreadPropsString =
|
|
872
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
873
|
+
return `<Heading${propsString}${spreadPropsString}>`;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// Handle Label components with special case for htmlFor prop
|
|
877
|
+
if (oldComponent === 'Label' && mapping.component === 'Text') {
|
|
878
|
+
// If htmlFor prop exists, add as="label" to ensure proper semantic HTML
|
|
879
|
+
// Otherwise, use existing as prop or default to undefined (no as prop)
|
|
880
|
+
const asValue = existingProps.htmlFor
|
|
881
|
+
? 'label'
|
|
882
|
+
: existingProps.as || undefined;
|
|
883
|
+
const variantValue = existingProps.variant || mapping.variant;
|
|
634
884
|
|
|
635
885
|
// Remove as and variant from props since we'll add them separately
|
|
636
886
|
delete newProps.as;
|
|
@@ -644,8 +894,13 @@ function updateComponents(content) {
|
|
|
644
894
|
}
|
|
645
895
|
Object.assign(orderedProps, newProps);
|
|
646
896
|
|
|
647
|
-
const propsString = propsToString(orderedProps);
|
|
648
|
-
|
|
897
|
+
const propsString = propsToString(orderedProps, originalSyntax);
|
|
898
|
+
const spreadPropsString =
|
|
899
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
900
|
+
|
|
901
|
+
// Only add as prop if it has a value
|
|
902
|
+
const asProp = asValue ? ` as="${asValue}"` : '';
|
|
903
|
+
return `<Text${asProp} variant="${variantValue}"${propsString}${spreadPropsString}>`;
|
|
649
904
|
}
|
|
650
905
|
|
|
651
906
|
// Handle other components
|
|
@@ -667,8 +922,10 @@ function updateComponents(content) {
|
|
|
667
922
|
});
|
|
668
923
|
Object.assign(finalProps, newProps);
|
|
669
924
|
|
|
670
|
-
const otherPropsString = propsToString(finalProps);
|
|
671
|
-
|
|
925
|
+
const otherPropsString = propsToString(finalProps, originalSyntax);
|
|
926
|
+
const spreadPropsString =
|
|
927
|
+
spreadProps.length > 0 ? ` {...${spreadProps.join(', ...')}}` : '';
|
|
928
|
+
return `<${componentName}${otherPropsString}${spreadPropsString}>`;
|
|
672
929
|
},
|
|
673
930
|
);
|
|
674
931
|
|
|
@@ -696,15 +953,33 @@ function updateComponents(content) {
|
|
|
696
953
|
* @returns {string[]} Array of matching file paths
|
|
697
954
|
*/
|
|
698
955
|
function findFiles(pattern) {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
956
|
+
const allFiles = [];
|
|
957
|
+
|
|
958
|
+
// Process directory patterns
|
|
959
|
+
const directoryPatterns = ALLOWED_DIRECTORIES.filter(dir =>
|
|
960
|
+
dir.includes('**'),
|
|
961
|
+
);
|
|
962
|
+
const filePatterns = ALLOWED_DIRECTORIES.filter(dir => !dir.includes('**'));
|
|
963
|
+
|
|
964
|
+
// Handle directory patterns (e.g., src/**, app/**)
|
|
965
|
+
if (directoryPatterns.length > 0) {
|
|
966
|
+
const combinedDirPattern = `{${directoryPatterns.join(',')}}/${pattern}`;
|
|
967
|
+
const dirFiles = glob.sync(combinedDirPattern, {
|
|
968
|
+
ignore: BLOCKED_DIRECTORIES,
|
|
969
|
+
nodir: true,
|
|
970
|
+
absolute: false,
|
|
971
|
+
});
|
|
972
|
+
allFiles.push(...dirFiles);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// Handle file patterns (e.g., *.jsx, *.tsx)
|
|
976
|
+
filePatterns.forEach(filePattern => {
|
|
977
|
+
const files = glob.sync(filePattern, {
|
|
978
|
+
ignore: BLOCKED_DIRECTORIES,
|
|
979
|
+
nodir: true,
|
|
980
|
+
absolute: false,
|
|
981
|
+
});
|
|
982
|
+
allFiles.push(...files);
|
|
708
983
|
});
|
|
709
984
|
|
|
710
985
|
// Use Set for efficient deduplication and filtering
|
|
@@ -725,37 +1000,29 @@ function findFiles(pattern) {
|
|
|
725
1000
|
return uniqueFiles;
|
|
726
1001
|
}
|
|
727
1002
|
|
|
728
|
-
function updateImportsAndComponents(content
|
|
1003
|
+
function updateImportsAndComponents(content) {
|
|
729
1004
|
let updatedContent = content;
|
|
730
1005
|
let changes = 0;
|
|
731
1006
|
let warnings = [];
|
|
732
1007
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
changes
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
content: finalContent,
|
|
745
|
-
changes: componentChanges,
|
|
746
|
-
warnings: componentWarnings,
|
|
747
|
-
} = updateComponents(newContent);
|
|
748
|
-
updatedContent = finalContent;
|
|
749
|
-
changes = importChanges + componentChanges;
|
|
750
|
-
warnings = componentWarnings;
|
|
751
|
-
}
|
|
1008
|
+
// Update both imports and components
|
|
1009
|
+
const { content: newContent, changes: importChanges } =
|
|
1010
|
+
updateImports(content);
|
|
1011
|
+
const {
|
|
1012
|
+
content: finalContent,
|
|
1013
|
+
changes: componentChanges,
|
|
1014
|
+
warnings: componentWarnings,
|
|
1015
|
+
} = updateComponents(newContent);
|
|
1016
|
+
updatedContent = finalContent;
|
|
1017
|
+
changes = importChanges + componentChanges;
|
|
1018
|
+
warnings = componentWarnings;
|
|
752
1019
|
|
|
753
1020
|
return { content: updatedContent, changes, warnings };
|
|
754
1021
|
}
|
|
755
1022
|
|
|
756
|
-
function generateMigrationReport(files,
|
|
1023
|
+
function generateMigrationReport(files, isDryRun = false) {
|
|
757
1024
|
const report = {
|
|
758
|
-
strategy,
|
|
1025
|
+
strategy: 'complete',
|
|
759
1026
|
totalFiles: files.length,
|
|
760
1027
|
migratedFiles: 0,
|
|
761
1028
|
totalChanges: 0,
|
|
@@ -776,7 +1043,7 @@ function generateMigrationReport(files, strategy, isDryRun = false) {
|
|
|
776
1043
|
content: updatedContent,
|
|
777
1044
|
changes,
|
|
778
1045
|
warnings,
|
|
779
|
-
} = updateImportsAndComponents(content
|
|
1046
|
+
} = updateImportsAndComponents(content);
|
|
780
1047
|
|
|
781
1048
|
// Combine migration warnings with file analysis warnings
|
|
782
1049
|
const allWarnings = [...warnings, ...fileAnalysis.warnings];
|
|
@@ -1006,23 +1273,13 @@ function printReport(report) {
|
|
|
1006
1273
|
}
|
|
1007
1274
|
}
|
|
1008
1275
|
|
|
1009
|
-
function showNextSteps(
|
|
1276
|
+
function showNextSteps() {
|
|
1010
1277
|
console.log('\n📝 Next Steps');
|
|
1011
1278
|
console.log('=============');
|
|
1012
1279
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
Object.entries(COMPONENT_MAPPING).forEach(([old, new_]) => {
|
|
1017
|
-
console.log(` ${old} → ${new_}`);
|
|
1018
|
-
});
|
|
1019
|
-
console.log('3. 🧪 Test your application');
|
|
1020
|
-
console.log('4. 📚 Read the migration guide on our website');
|
|
1021
|
-
} else if (strategy === 'complete') {
|
|
1022
|
-
console.log('1. 🧪 Test your application thoroughly');
|
|
1023
|
-
console.log('2. 🔄 Review and adjust any component props if needed');
|
|
1024
|
-
console.log('3. 📚 Read the migration guide on our website');
|
|
1025
|
-
}
|
|
1280
|
+
console.log('1. 🧪 Test your application thoroughly');
|
|
1281
|
+
console.log('2. 🔄 Review and adjust any component props if needed');
|
|
1282
|
+
console.log('3. 📚 Read the migration guide on our website');
|
|
1026
1283
|
|
|
1027
1284
|
console.log('\n⚠️ Important Notes:');
|
|
1028
1285
|
console.log('- Check warnings above for potential issues');
|
|
@@ -1030,7 +1287,7 @@ function showNextSteps(strategy) {
|
|
|
1030
1287
|
console.log('- Test thoroughly, especially components with custom styling');
|
|
1031
1288
|
}
|
|
1032
1289
|
|
|
1033
|
-
function main() {
|
|
1290
|
+
async function main() {
|
|
1034
1291
|
// Show help if requested
|
|
1035
1292
|
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
1036
1293
|
console.log('🎨 Typography Migration Script');
|
|
@@ -1047,40 +1304,34 @@ function main() {
|
|
|
1047
1304
|
console.log(' # Local development');
|
|
1048
1305
|
console.log(' npm run migrate');
|
|
1049
1306
|
console.log('');
|
|
1050
|
-
console.log('
|
|
1307
|
+
console.log('📋 Prerequisites:');
|
|
1308
|
+
console.log(' - Install glob package: npm install glob');
|
|
1051
1309
|
console.log(
|
|
1052
|
-
'
|
|
1310
|
+
' - Or use npx/yarn dlx which handles dependencies automatically',
|
|
1053
1311
|
);
|
|
1312
|
+
console.log('');
|
|
1313
|
+
console.log('Options:');
|
|
1054
1314
|
console.log(
|
|
1055
|
-
' --
|
|
1315
|
+
' --dry-run Show what would be changed without modifying files',
|
|
1056
1316
|
);
|
|
1057
|
-
|
|
1058
1317
|
console.log(' --help, -h Show this help message');
|
|
1059
1318
|
console.log('');
|
|
1060
|
-
console.log('Migration
|
|
1061
|
-
console.log(' 🚀 Complete Mode
|
|
1319
|
+
console.log('Migration Mode:');
|
|
1320
|
+
console.log(' 🚀 Complete Mode: Updates everything');
|
|
1062
1321
|
console.log(' - Replaces old components with beta components');
|
|
1063
|
-
console.log(' -
|
|
1322
|
+
console.log(' - Heading1-6 → Heading with as/variant props');
|
|
1323
|
+
console.log(' - Text components → Text with variant props');
|
|
1324
|
+
console.log(' - All typography components migrate to beta versions');
|
|
1325
|
+
console.log(' - Import paths change to @entur/typography/beta');
|
|
1326
|
+
console.log(' - May require prop/styling updates (margin → spacing)');
|
|
1064
1327
|
console.log(' - Test thoroughly after migration');
|
|
1065
1328
|
console.log('');
|
|
1066
|
-
console.log(
|
|
1067
|
-
' 📝 Import-Only Mode (--import-only): Only updates import paths',
|
|
1068
|
-
);
|
|
1069
|
-
console.log(' - Keeps your existing component usage unchanged');
|
|
1070
|
-
console.log(' - Minimal risk, gradual migration');
|
|
1071
|
-
console.log('');
|
|
1072
1329
|
console.log('Examples:');
|
|
1073
1330
|
console.log(' # See what would be changed');
|
|
1074
1331
|
console.log(' npx @entur/typography@latest migrate --dry-run');
|
|
1075
1332
|
console.log('');
|
|
1076
1333
|
console.log(' # Complete migration: update everything (default)');
|
|
1077
1334
|
console.log(' npx @entur/typography@latest migrate');
|
|
1078
|
-
console.log('');
|
|
1079
|
-
console.log(' # Import-only migration: update import paths only');
|
|
1080
|
-
console.log(' npx @entur/typography@latest migrate --import-only');
|
|
1081
|
-
console.log('');
|
|
1082
|
-
|
|
1083
|
-
console.log('');
|
|
1084
1335
|
|
|
1085
1336
|
console.log('Environment Variables:');
|
|
1086
1337
|
console.log(
|
|
@@ -1096,7 +1347,7 @@ function main() {
|
|
|
1096
1347
|
console.log(' Add/remove folder patterns between the 👇 and 👆 markers');
|
|
1097
1348
|
console.log(' Examples: "src/**", "app/**", "packages/my-app/**"');
|
|
1098
1349
|
console.log('');
|
|
1099
|
-
console.log(' Option 2: Set environment variable
|
|
1350
|
+
console.log(' Option 2: Set environment variable');
|
|
1100
1351
|
console.log(
|
|
1101
1352
|
' export TYPOGRAPHY_MIGRATION_DIRS="src/**,app/**,components/**"',
|
|
1102
1353
|
);
|
|
@@ -1164,47 +1415,48 @@ function main() {
|
|
|
1164
1415
|
|
|
1165
1416
|
// Parse command line options
|
|
1166
1417
|
const isDryRun = process.argv.includes('--dry-run');
|
|
1167
|
-
const isImportOnly = process.argv.includes('--import-only');
|
|
1168
1418
|
|
|
1169
1419
|
if (isDryRun) {
|
|
1170
1420
|
console.log('🔍 DRY RUN MODE: No files will be modified');
|
|
1171
1421
|
console.log('');
|
|
1172
1422
|
}
|
|
1173
1423
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1424
|
+
console.log('🚀 COMPLETE MIGRATION: Updating imports + component usage');
|
|
1425
|
+
console.log('⚠️ WARNING: This will modify your component usage!');
|
|
1426
|
+
console.log(' - Old components will be replaced with beta components');
|
|
1427
|
+
console.log(' - Import paths will change to @entur/typography/beta');
|
|
1428
|
+
console.log(
|
|
1429
|
+
' - Link → Link, Blockquote → Blockquote, Lists → List components (from beta)',
|
|
1430
|
+
);
|
|
1431
|
+
console.log(
|
|
1432
|
+
' - List components → UnorderedList, NumberedList, ListItem (from beta)',
|
|
1433
|
+
);
|
|
1434
|
+
console.log(' - Props may change (margin → spacing)');
|
|
1435
|
+
console.log(' - Test thoroughly after migration');
|
|
1186
1436
|
|
|
1187
1437
|
console.log('');
|
|
1188
1438
|
|
|
1189
1439
|
// Perform migration
|
|
1190
|
-
const report = generateMigrationReport(
|
|
1191
|
-
allFiles,
|
|
1192
|
-
isImportOnly ? 'import-only' : 'complete',
|
|
1193
|
-
isDryRun,
|
|
1194
|
-
);
|
|
1440
|
+
const report = generateMigrationReport(allFiles, isDryRun);
|
|
1195
1441
|
printReport(report);
|
|
1196
|
-
showNextSteps(
|
|
1442
|
+
showNextSteps();
|
|
1197
1443
|
|
|
1198
1444
|
console.log('\n🎯 Migration complete!');
|
|
1199
1445
|
}
|
|
1200
1446
|
|
|
1201
|
-
if
|
|
1202
|
-
|
|
1447
|
+
// Check if this module is being run directly
|
|
1448
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
1449
|
+
main().catch(error => {
|
|
1450
|
+
console.error('❌ Migration failed:', error);
|
|
1451
|
+
process.exit(1);
|
|
1452
|
+
});
|
|
1203
1453
|
}
|
|
1204
1454
|
|
|
1205
|
-
|
|
1455
|
+
export {
|
|
1206
1456
|
updateImportsAndComponents,
|
|
1207
1457
|
generateMigrationReport,
|
|
1208
1458
|
COMPONENT_MAPPING,
|
|
1209
1459
|
PROPS_MAPPING,
|
|
1460
|
+
parseJSXProps,
|
|
1461
|
+
propsToString,
|
|
1210
1462
|
};
|