@navikt/aksel 7.34.0 → 7.35.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 +96 -2
- package/dist/codemod/codeshift.utils.js +9 -1
- package/dist/codemod/migrations.js +75 -22
- package/dist/codemod/run-codeshift.js +14 -3
- package/dist/codemod/transforms/v8.0.0/accordion-variant/accordion-variant.js +16 -0
- package/dist/codemod/transforms/{darkside/box-to-boxnew/box-to-boxnew.js → v8.0.0/box/box.js} +80 -100
- package/dist/codemod/transforms/v8.0.0/box-new/box-new.js +91 -0
- package/dist/codemod/transforms/v8.0.0/chips-variant/chips-variant.js +31 -0
- package/dist/codemod/transforms/v8.0.0/list/list.js +218 -0
- package/dist/codemod/transforms/{darkside → v8.0.0}/prop-deprecate/prop-deprecate.js +1 -1
- package/dist/codemod/transforms/v8.0.0/tag-variant/tag-variant.js +38 -0
- package/dist/codemod/transforms/v8.0.0/toggle-group-variant/toggle-group-variant.js +16 -0
- package/dist/codemod/utils/ast.js +1 -1
- package/dist/codemod/utils/check.js +35 -0
- package/dist/codemod/utils/move-variant-to-data-color.js +120 -0
- package/dist/darkside/index.js +3 -9
- package/dist/darkside/run-tooling.js +138 -42
- package/dist/darkside/tasks/print-remaining.js +143 -38
- package/dist/darkside/tasks/status.js +147 -30
- package/dist/darkside/transforms/darkside-tokens-css.js +23 -8
- package/dist/darkside/transforms/darkside-tokens-tailwind.js +9 -10
- package/dist/help.js +0 -10
- package/dist/index.js +14 -17
- package/package.json +7 -7
- package/dist/css-imports/config.js +0 -5
- package/dist/css-imports/generate-output.js +0 -147
- package/dist/css-imports/get-directories.js +0 -34
- package/dist/css-imports/get-version.js +0 -28
- package/dist/css-imports/index.js +0 -187
- package/dist/css-imports/inquiry.js +0 -35
- package/dist/css-imports/scan-code.js +0 -45
- /package/dist/codemod/transforms/{spacing → v8.0.0}/primitives-spacing/spacing.js +0 -0
- /package/dist/codemod/transforms/{spacing → v8.0.0}/spacing.utils.js +0 -0
- /package/dist/codemod/transforms/{spacing → v8.0.0}/token-spacing/spacing.js +0 -0
- /package/dist/codemod/transforms/{spacing → v8.0.0}/token-spacing-js/spacing.js +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Aksel command line interface
|
|
2
2
|
|
|
3
|
-
CLI tool for
|
|
3
|
+
CLI tool for running codemods when consuming Aksel-packages.
|
|
4
4
|
|
|
5
5
|
[Documentation](https://aksel.nav.no/preview/grunnleggende/kode/kommandolinje)
|
|
6
6
|
|
|
@@ -9,7 +9,6 @@ run:
|
|
|
9
9
|
npx @navikt/aksel
|
|
10
10
|
|
|
11
11
|
commands:
|
|
12
|
-
css-imports: Generate css-imports for all components from Aksel
|
|
13
12
|
codemod: Codemods for version-migrations related to Aksel
|
|
14
13
|
```
|
|
15
14
|
|
|
@@ -22,6 +21,101 @@ To get started:
|
|
|
22
21
|
npx @navikt/aksel codemod --help
|
|
23
22
|
```
|
|
24
23
|
|
|
24
|
+
### v8
|
|
25
|
+
|
|
26
|
+
#### Box
|
|
27
|
+
|
|
28
|
+
`npx @navikt/aksel codemod v8-box ...`
|
|
29
|
+
|
|
30
|
+
Updates Box with legacy-tokens to Box using the new token system.
|
|
31
|
+
|
|
32
|
+
```diff
|
|
33
|
+
-<Box background="bg-subtle" borderColor="border-alt-1">
|
|
34
|
+
+<Box background="bg-neutral-soft" borderColor="border-meta-purple">
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### BoxNew
|
|
38
|
+
|
|
39
|
+
`npx @navikt/aksel codemod v8-box-new ...`
|
|
40
|
+
|
|
41
|
+
Renames already migrated BoxNew/Box.New instances to Box.
|
|
42
|
+
|
|
43
|
+
```diff
|
|
44
|
+
-<BoxNew>
|
|
45
|
+
+<Box>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Prop deprecate
|
|
49
|
+
|
|
50
|
+
`npx @navikt/aksel codemod v8-prop-deprecate ...`
|
|
51
|
+
|
|
52
|
+
Removes deprecated props from components.
|
|
53
|
+
|
|
54
|
+
```diff
|
|
55
|
+
-<Accordion headingSize="large">
|
|
56
|
+
+<Accordion>
|
|
57
|
+
|
|
58
|
+
-<Popover arrow>
|
|
59
|
+
+<Popover>
|
|
60
|
+
|
|
61
|
+
-<Page background="bg-subtle">
|
|
62
|
+
+<Page>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### List
|
|
66
|
+
|
|
67
|
+
`npx @navikt/aksel codemod v8-list ...`
|
|
68
|
+
|
|
69
|
+
Tries to migrate List component moving 'title' and 'description' props to 'Heading' and 'BodyShort'.
|
|
70
|
+
|
|
71
|
+
#### Variants
|
|
72
|
+
|
|
73
|
+
`npx @navikt/aksel codemod v8-tag-variant ...`
|
|
74
|
+
`npx @navikt/aksel codemod v8-toggle-group-variant ...`
|
|
75
|
+
`npx @navikt/aksel codemod v8-accordion-variant ...`
|
|
76
|
+
`npx @navikt/aksel codemod v8-chips-variant ...`
|
|
77
|
+
|
|
78
|
+
Updates variant + data-color props based on current variant prop.
|
|
79
|
+
|
|
80
|
+
```diff
|
|
81
|
+
-<Tag variant="info">
|
|
82
|
+
+<Tag variant="outline" data-color="info">
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Spacing
|
|
86
|
+
|
|
87
|
+
`npx @navikt/aksel codemod v8-primitive-spacing ...`
|
|
88
|
+
`npx @navikt/aksel codemod v8-token-spacing ...`
|
|
89
|
+
`npx @navikt/aksel codemod v8-token-spacing-js ...`
|
|
90
|
+
|
|
91
|
+
Updates use of legacy `spacing` token to new `space`-token
|
|
92
|
+
|
|
93
|
+
```diff
|
|
94
|
+
-<HStack gap="spacing-4" />
|
|
95
|
+
+<HStack gap="space-16" />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```diff
|
|
99
|
+
-margin: var(--a-spacing-1);
|
|
100
|
+
+margin: var(--ax-space-4);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### v6
|
|
104
|
+
|
|
105
|
+
#### Chat
|
|
106
|
+
|
|
107
|
+
`npx @navikt/aksel codemod v6-chat ...`
|
|
108
|
+
|
|
109
|
+
Removes `backgroundColor` and `avatarBgColor` properties from `Chat` and `Chat.Bubble`.
|
|
110
|
+
|
|
111
|
+
```diff
|
|
112
|
+
-<Chat backgroundColor="red" avatarBgColor="blue">
|
|
113
|
+
+<Chat>
|
|
114
|
+
- <Chat.Bubble backgroundColor="red" />
|
|
115
|
+
+ <Chat.Bubble />
|
|
116
|
+
</Chat>
|
|
117
|
+
```
|
|
118
|
+
|
|
25
119
|
### v4
|
|
26
120
|
|
|
27
121
|
In v4, we moved all the components from `@navikt/ds-react-internal` to `@navikt/ds-react`. This means that you will need to update all your imports to the new package. As a part of this, Header was renamed to `InternalHeader` and all the CSS-classes was renamed to use `navds` as a prefix instead of `navdsi`.
|
|
@@ -17,7 +17,15 @@ exports.GLOB_IGNORE_PATTERNS = GLOB_IGNORE_PATTERNS;
|
|
|
17
17
|
*/
|
|
18
18
|
function getDefaultGlob(ext) {
|
|
19
19
|
const defaultExt = "js,ts,jsx,tsx,css,scss,less";
|
|
20
|
-
|
|
20
|
+
const extensions = cleanExtensions(ext !== null && ext !== void 0 ? ext : defaultExt);
|
|
21
|
+
/**
|
|
22
|
+
* Single-item braces are treated as a literal string by some globbing libraries,
|
|
23
|
+
* so we only use them when there are multiple extensions
|
|
24
|
+
*/
|
|
25
|
+
if (extensions.length > 1) {
|
|
26
|
+
return `**/*.{${extensions.join(",")}}`;
|
|
27
|
+
}
|
|
28
|
+
return `**/*.${extensions[0]}`;
|
|
21
29
|
}
|
|
22
30
|
/**
|
|
23
31
|
* Utility function to clean file extensions
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.migrations = void 0;
|
|
6
|
+
exports.migrationStringOverride = exports.migrations = void 0;
|
|
7
7
|
exports.getMigrationPath = getMigrationPath;
|
|
8
8
|
exports.getWarning = getWarning;
|
|
9
9
|
exports.getIgnoredFileExtensions = getIgnoredFileExtensions;
|
|
@@ -79,7 +79,7 @@ exports.migrations = {
|
|
|
79
79
|
description: "Replaces deprecated <CopyToClipboard /> with <CopyButton />",
|
|
80
80
|
value: "v3-copybutton",
|
|
81
81
|
path: "v3.0.0/copybutton/copybutton",
|
|
82
|
-
warning: "Remember to
|
|
82
|
+
warning: "Remember to remove css-import from '@navikt/ds-css-internal' if no longer needed\nIf non-text was used as children, or different locales were handled, you need to manually fix this",
|
|
83
83
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
84
84
|
},
|
|
85
85
|
],
|
|
@@ -114,38 +114,72 @@ exports.migrations = {
|
|
|
114
114
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
115
115
|
},
|
|
116
116
|
],
|
|
117
|
-
|
|
117
|
+
"v8.0.0": [
|
|
118
118
|
{
|
|
119
|
-
description: "Updates
|
|
120
|
-
value: "
|
|
121
|
-
path: "
|
|
119
|
+
description: "Updates Box with legacy-tokens to Box using the new token system, and renames already migrated BoxNew/Box.New instances to Box.",
|
|
120
|
+
value: "v8-box",
|
|
121
|
+
path: "v8.0.0/box/box",
|
|
122
|
+
warning: "Remember to check if 'TODO: Aksel Box migration'-comment was added to any files after migration. This comment will help you find and update Box-instances we couldn't update for you.",
|
|
122
123
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
123
124
|
},
|
|
124
125
|
{
|
|
125
|
-
description: "
|
|
126
|
-
value: "
|
|
127
|
-
path: "
|
|
128
|
-
ignoredExtensions:
|
|
126
|
+
description: "Renames already migrated BoxNew/Box.New instances to Box.",
|
|
127
|
+
value: "v8-box-new",
|
|
128
|
+
path: "v8.0.0/box-new/box-new",
|
|
129
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
129
130
|
},
|
|
130
131
|
{
|
|
131
|
-
description: "
|
|
132
|
-
value: "
|
|
133
|
-
path: "
|
|
132
|
+
description: "Removes deprecated props from components.",
|
|
133
|
+
value: "v8-prop-deprecate",
|
|
134
|
+
path: "v8.0.0/prop-deprecate/prop-deprecate",
|
|
135
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
description: "Updates variant + data-color props on Tag based on current variant prop.",
|
|
139
|
+
value: "v8-tag-variant",
|
|
140
|
+
path: "v8.0.0/tag-variant/tag-variant",
|
|
134
141
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
135
142
|
},
|
|
136
|
-
],
|
|
137
|
-
darkside: [
|
|
138
143
|
{
|
|
139
|
-
description: "
|
|
140
|
-
value: "
|
|
141
|
-
path: "
|
|
144
|
+
description: "Updates variant + data-color props on ToggleGroup based on current variant prop.",
|
|
145
|
+
value: "v8-toggle-group-variant",
|
|
146
|
+
path: "v8.0.0/toggle-group-variant/toggle-group-variant",
|
|
142
147
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
143
148
|
},
|
|
144
149
|
{
|
|
145
|
-
description: "
|
|
146
|
-
value: "
|
|
147
|
-
path: "
|
|
148
|
-
|
|
150
|
+
description: "Updates variant + data-color props on Accordion based on current variant prop.",
|
|
151
|
+
value: "v8-accordion-variant",
|
|
152
|
+
path: "v8.0.0/accordion-variant/accordion-variant",
|
|
153
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
description: "Updates variant + data-color props on Chips based on current variant prop.",
|
|
157
|
+
value: "v8-chips-variant",
|
|
158
|
+
path: "v8.0.0/chips-variant/chips-variant",
|
|
159
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
description: "Tries to migrate List component moving 'title' and 'description' props to 'Heading' and 'BodyShort'.",
|
|
163
|
+
value: "v8-list",
|
|
164
|
+
path: "v8.0.0/list/list",
|
|
165
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
description: "Updates all Primitives to use new `space`-tokens. (Works with old and new system)",
|
|
169
|
+
value: "v8-primitive-spacing",
|
|
170
|
+
path: "v8.0.0/primitives-spacing/spacing",
|
|
171
|
+
ignoredExtensions: CSS_EXTENSIONS,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
description: "Updates css, scss and less-variables to use new `space`-tokens. (Works with old and new system)",
|
|
175
|
+
value: "v8-token-spacing",
|
|
176
|
+
path: "v8.0.0/token-spacing/spacing",
|
|
177
|
+
ignoredExtensions: [],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
description: "Updates js-tokens to use new `space`-tokens. (Works with old and new system)",
|
|
181
|
+
value: "v8-token-spacing-js",
|
|
182
|
+
path: "v8.0.0/token-spacing-js/spacing",
|
|
149
183
|
ignoredExtensions: CSS_EXTENSIONS,
|
|
150
184
|
},
|
|
151
185
|
],
|
|
@@ -182,6 +216,21 @@ function getMigrationNames() {
|
|
|
182
216
|
.flat()
|
|
183
217
|
.map((x) => x.value);
|
|
184
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Allows injecting additional migration names that are not part of the main migrations-list.
|
|
221
|
+
* This is used for interactive migrations that should not be part of the main list.
|
|
222
|
+
*
|
|
223
|
+
* We need to separate this since main migration list expect all migration names to have a unique path,
|
|
224
|
+
* which is not the case for interactive migrations that are handled differently.
|
|
225
|
+
*/
|
|
226
|
+
exports.migrationStringOverride = {
|
|
227
|
+
"v8.0.0": [
|
|
228
|
+
{
|
|
229
|
+
value: "v8-tokens",
|
|
230
|
+
description: "Starts interactive token migration for v8",
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
};
|
|
185
234
|
function getMigrationString() {
|
|
186
235
|
let str = "";
|
|
187
236
|
Object.entries(exports.migrations).forEach(([version, vMigrations]) => {
|
|
@@ -189,6 +238,10 @@ function getMigrationString() {
|
|
|
189
238
|
vMigrations.forEach((migration) => {
|
|
190
239
|
str += `${chalk_1.default.blue(migration.value)}: ${migration.description}\n`;
|
|
191
240
|
});
|
|
241
|
+
const overrideMigrations = exports.migrationStringOverride[version] || [];
|
|
242
|
+
overrideMigrations.forEach((migration) => {
|
|
243
|
+
str += `${chalk_1.default.blue(migration.value)}: ${migration.description}\n`;
|
|
244
|
+
});
|
|
192
245
|
});
|
|
193
246
|
return str;
|
|
194
247
|
}
|
|
@@ -63,12 +63,23 @@ function runCodeshift(input, options, program) {
|
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
64
|
var _a;
|
|
65
65
|
const codemodPath = node_path_1.default.join(__dirname, `./transforms/${(0, migrations_1.getMigrationPath)(input)}.js`);
|
|
66
|
-
|
|
66
|
+
console.info(chalk_1.default.greenBright.bold("\nWelcome to Aksel codemods!"));
|
|
67
|
+
console.info("\nRunning migration:", chalk_1.default.green(input));
|
|
68
|
+
const globList = (_a = options.glob) !== null && _a !== void 0 ? _a : (0, codeshift_utils_1.getDefaultGlob)(options === null || options === void 0 ? void 0 : options.ext);
|
|
69
|
+
console.info(chalk_1.default.gray(`Using glob pattern(s): ${globList}\nWorking directory: ${process.cwd()}\n`));
|
|
70
|
+
const filepaths = fast_glob_1.default.sync(globList, {
|
|
67
71
|
cwd: process.cwd(),
|
|
68
72
|
ignore: codeshift_utils_1.GLOB_IGNORE_PATTERNS,
|
|
73
|
+
/**
|
|
74
|
+
* When globbing, do not follow symlinks to avoid processing files outside the directory.
|
|
75
|
+
* This is most likely to happen in monorepos where node_modules may contain symlinks to packages
|
|
76
|
+
* in other parts of the repo.
|
|
77
|
+
*
|
|
78
|
+
* While node_modules is already ignored via GLOB_IGNORE_PATTERNS, if user globs upwards (e.g., using '../src/**'),
|
|
79
|
+
* that ignore-pattern may be ignored, leading to unintended file processing.
|
|
80
|
+
*/
|
|
81
|
+
followSymbolicLinks: false,
|
|
69
82
|
});
|
|
70
|
-
console.info("\nRunning migration:", chalk_1.default.green("input"));
|
|
71
|
-
(options === null || options === void 0 ? void 0 : options.glob) && console.info(`Using glob: ${chalk_1.default.green(options.glob)}\n`);
|
|
72
83
|
const warning = (0, migrations_1.getWarning)(input);
|
|
73
84
|
const unsafeExtensions = (0, migrations_1.getIgnoredFileExtensions)(input);
|
|
74
85
|
let safeFilepaths = filepaths;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrationConfig = void 0;
|
|
4
|
+
exports.default = transformer;
|
|
5
|
+
const move_variant_to_data_color_1 = require("../../../utils/move-variant-to-data-color");
|
|
6
|
+
exports.migrationConfig = {
|
|
7
|
+
component: "Accordion",
|
|
8
|
+
prop: "variant",
|
|
9
|
+
changes: {
|
|
10
|
+
default: { color: "accent" },
|
|
11
|
+
neutral: { color: "neutral" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
function transformer(file, api) {
|
|
15
|
+
return (0, move_variant_to_data_color_1.moveVariantToDataColor)(file, api, exports.migrationConfig);
|
|
16
|
+
}
|
package/dist/codemod/transforms/{darkside/box-to-boxnew/box-to-boxnew.js → v8.0.0/box/box.js}
RENAMED
|
@@ -1,49 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
35
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
6
|
exports.default = transformer;
|
|
37
7
|
const legacy_tokens_1 = require("../../../../darkside/config/legacy.tokens");
|
|
38
8
|
const ast_1 = require("../../../utils/ast");
|
|
39
9
|
const lineterminator_1 = require("../../../utils/lineterminator");
|
|
40
|
-
const
|
|
10
|
+
const box_new_1 = __importDefault(require("../box-new/box-new"));
|
|
41
11
|
const propsAffected = ["background", "borderColor", "shadow"];
|
|
42
12
|
function transformer(file, api) {
|
|
43
13
|
const j = api.jscodeshift;
|
|
44
14
|
const root = j(file.source);
|
|
45
15
|
const toSourceOptions = (0, lineterminator_1.getLineTerminator)(file.source);
|
|
46
|
-
if (file.source.includes("TODO:
|
|
16
|
+
if (file.source.includes("TODO: Aksel Box migration")) {
|
|
47
17
|
return root.toSource(toSourceOptions);
|
|
48
18
|
}
|
|
49
19
|
const localName = (0, ast_1.findComponentImport)({
|
|
@@ -63,19 +33,24 @@ function transformer(file, api) {
|
|
|
63
33
|
},
|
|
64
34
|
},
|
|
65
35
|
});
|
|
36
|
+
const predefinedReplacents = predefinedReplacentset();
|
|
66
37
|
const tokenComments = [];
|
|
67
38
|
for (const astElement of astElements.paths()) {
|
|
68
|
-
let encounteredUnmigratableProp = false;
|
|
69
39
|
for (const prop of propsAffected) {
|
|
70
40
|
(0, ast_1.findProps)({ j, path: astElement, name: prop }).forEach((attr) => {
|
|
71
41
|
const attrvalue = attr.value.value;
|
|
72
42
|
if (attrvalue.type === "StringLiteral") {
|
|
43
|
+
/**
|
|
44
|
+
* Skips if the replacement token already set
|
|
45
|
+
*/
|
|
46
|
+
if (predefinedReplacents.has(addPrefix(attrvalue.value, prop))) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
73
49
|
const config = legacy_tokens_1.legacyTokenConfig[attrvalue.value];
|
|
74
50
|
if (config === null || config === void 0 ? void 0 : config.replacement) {
|
|
75
|
-
attrvalue.value = config.replacement;
|
|
51
|
+
attrvalue.value = cleanReplacementToken(config.replacement, prop);
|
|
76
52
|
}
|
|
77
53
|
else {
|
|
78
|
-
encounteredUnmigratableProp = true;
|
|
79
54
|
const tokenComment = {
|
|
80
55
|
prop,
|
|
81
56
|
token: attrvalue.value,
|
|
@@ -86,6 +61,30 @@ function transformer(file, api) {
|
|
|
86
61
|
tokenComments.push(tokenComment);
|
|
87
62
|
}
|
|
88
63
|
}
|
|
64
|
+
else if (attrvalue.type === "JSXExpressionContainer" &&
|
|
65
|
+
attrvalue.expression.type === "StringLiteral") {
|
|
66
|
+
const literal = attrvalue.expression;
|
|
67
|
+
/**
|
|
68
|
+
* Skips if the replacement token already set
|
|
69
|
+
*/
|
|
70
|
+
if (predefinedReplacents.has(addPrefix(literal.value, prop))) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const config = legacy_tokens_1.legacyTokenConfig[literal.value];
|
|
74
|
+
if (config === null || config === void 0 ? void 0 : config.replacement) {
|
|
75
|
+
literal.value = cleanReplacementToken(config.replacement, prop);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const tokenComment = {
|
|
79
|
+
prop,
|
|
80
|
+
token: literal.value,
|
|
81
|
+
};
|
|
82
|
+
if (config === null || config === void 0 ? void 0 : config.comment) {
|
|
83
|
+
tokenComment.comment = config.comment;
|
|
84
|
+
}
|
|
85
|
+
tokenComments.push(tokenComment);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
89
88
|
});
|
|
90
89
|
}
|
|
91
90
|
(0, ast_1.findProps)({ j, path: astElement, name: "borderRadius" }).forEach((attr) => {
|
|
@@ -107,46 +106,24 @@ function transformer(file, api) {
|
|
|
107
106
|
}
|
|
108
107
|
});
|
|
109
108
|
}
|
|
109
|
+
else if (expression.type === "StringLiteral") {
|
|
110
|
+
expression.value = convertBorderRadiusToRadius(expression.value);
|
|
111
|
+
}
|
|
110
112
|
}
|
|
111
113
|
});
|
|
112
|
-
if (!encounteredUnmigratableProp) {
|
|
113
|
-
// TODO: ?? Box -> BoxNew type fail? (but works)
|
|
114
|
-
astElement.node.openingElement.name.name = "BoxNew";
|
|
115
|
-
astElement.node.closingElement.name.name = "BoxNew";
|
|
116
|
-
}
|
|
117
114
|
}
|
|
118
115
|
const blockComment = createFileComments({ tokenComments });
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// WHY: we do nothing to the import statements if we couldn't migrate any Box
|
|
122
|
-
}
|
|
123
|
-
if (importAnalysis === "mixed") {
|
|
124
|
-
// WHY: mixed Box and BoxNew == we keep old, and add the new import
|
|
125
|
-
(0, packageImports_1.addPackageImport)({
|
|
126
|
-
j,
|
|
127
|
-
root,
|
|
128
|
-
packageName: "@navikt/ds-react/Box",
|
|
129
|
-
specifiers: ["BoxNew"],
|
|
130
|
-
});
|
|
116
|
+
if (blockComment) {
|
|
117
|
+
return `${blockComment ? blockComment + "\n\n" : ""}${root.toSource(toSourceOptions)}`;
|
|
131
118
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
(0, packageImports_1.default)(j, root, {
|
|
135
|
-
fromImport: "@navikt/ds-react",
|
|
136
|
-
toImport: "@navikt/ds-react/Box",
|
|
137
|
-
fromName: "Box",
|
|
138
|
-
toName: "BoxNew",
|
|
139
|
-
ignoreAlias: true,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
const output = `${blockComment ? blockComment + "\n\n" : ""}${root.toSource(toSourceOptions)}`;
|
|
143
|
-
return output;
|
|
119
|
+
file.source = root.toSource(toSourceOptions);
|
|
120
|
+
return (0, box_new_1.default)(file, api);
|
|
144
121
|
}
|
|
145
122
|
const createFileComments = ({ tokenComments, }) => {
|
|
146
123
|
if (tokenComments.length === 0) {
|
|
147
124
|
return null;
|
|
148
125
|
}
|
|
149
|
-
let constructedComment = "/*\nTODO:
|
|
126
|
+
let constructedComment = "/*\nTODO: Aksel Box migration:\nCould not migrate the following:\n";
|
|
150
127
|
for (const { prop, token, comment } of tokenComments.values()) {
|
|
151
128
|
constructedComment += ` - ${prop}=${token}\n`;
|
|
152
129
|
if (comment) {
|
|
@@ -156,38 +133,6 @@ const createFileComments = ({ tokenComments, }) => {
|
|
|
156
133
|
constructedComment += "*/";
|
|
157
134
|
return constructedComment;
|
|
158
135
|
};
|
|
159
|
-
const analyzePartialMigration = (j, source) => {
|
|
160
|
-
const root = j(source);
|
|
161
|
-
const astNewElements = (0, ast_1.findJSXElement)({
|
|
162
|
-
root,
|
|
163
|
-
j,
|
|
164
|
-
name: "BoxNew",
|
|
165
|
-
originalName: "BoxNew",
|
|
166
|
-
});
|
|
167
|
-
if (astNewElements.length === 0) {
|
|
168
|
-
return "no new";
|
|
169
|
-
}
|
|
170
|
-
const localName = (0, ast_1.findComponentImport)({
|
|
171
|
-
root,
|
|
172
|
-
j,
|
|
173
|
-
name: "Box",
|
|
174
|
-
packageType: "react",
|
|
175
|
-
});
|
|
176
|
-
if (!localName) {
|
|
177
|
-
// this should never happen
|
|
178
|
-
throw new Error('package imports have been tampered with before the package import "step" in the migration');
|
|
179
|
-
}
|
|
180
|
-
const astOldElements = (0, ast_1.findJSXElement)({
|
|
181
|
-
root,
|
|
182
|
-
j,
|
|
183
|
-
name: localName,
|
|
184
|
-
originalName: "Box",
|
|
185
|
-
});
|
|
186
|
-
if (astOldElements.length === 0) {
|
|
187
|
-
return "all new";
|
|
188
|
-
}
|
|
189
|
-
return "mixed";
|
|
190
|
-
};
|
|
191
136
|
const legacyBorderRadiusNameTokenLookup = {
|
|
192
137
|
full: "full",
|
|
193
138
|
xlarge: "12",
|
|
@@ -217,3 +162,38 @@ function convertBorderRadiusToRadius(oldValue) {
|
|
|
217
162
|
}
|
|
218
163
|
return newRadius.join(" ");
|
|
219
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* New props in Box do not have bg- or border- prefixes
|
|
167
|
+
* This function removes those prefixes from the tokens
|
|
168
|
+
*/
|
|
169
|
+
function cleanReplacementToken(token, type) {
|
|
170
|
+
if (type === "background") {
|
|
171
|
+
return token.replace("bg-", "");
|
|
172
|
+
}
|
|
173
|
+
if (type === "borderColor") {
|
|
174
|
+
return token.replace("border-", "");
|
|
175
|
+
}
|
|
176
|
+
return token;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Adds bg- or border- prefixes to tokens for comparison with existing replacements
|
|
180
|
+
*/
|
|
181
|
+
function addPrefix(token, type) {
|
|
182
|
+
if (type === "background") {
|
|
183
|
+
return `bg-${token}`;
|
|
184
|
+
}
|
|
185
|
+
if (type === "borderColor") {
|
|
186
|
+
return `border-${token}`;
|
|
187
|
+
}
|
|
188
|
+
return token;
|
|
189
|
+
}
|
|
190
|
+
function predefinedReplacentset() {
|
|
191
|
+
const set = new Set();
|
|
192
|
+
for (const key in legacy_tokens_1.legacyTokenConfig) {
|
|
193
|
+
const config = legacy_tokens_1.legacyTokenConfig[key];
|
|
194
|
+
if (config.replacement) {
|
|
195
|
+
set.add(config.replacement);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return set;
|
|
199
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = transformer;
|
|
4
|
+
const ast_1 = require("../../../utils/ast");
|
|
5
|
+
const lineterminator_1 = require("../../../utils/lineterminator");
|
|
6
|
+
function transformer(file, api) {
|
|
7
|
+
const j = api.jscodeshift;
|
|
8
|
+
const root = j(file.source);
|
|
9
|
+
const toSourceOptions = (0, lineterminator_1.getLineTerminator)(file.source);
|
|
10
|
+
const boxLocalName = (0, ast_1.findComponentImport)({
|
|
11
|
+
root,
|
|
12
|
+
j,
|
|
13
|
+
name: "Box",
|
|
14
|
+
packageType: "react",
|
|
15
|
+
}) || "Box";
|
|
16
|
+
// Rename <BoxNew ...> to <Box ...>
|
|
17
|
+
root.find(j.JSXOpeningElement).forEach((path) => {
|
|
18
|
+
if (path.value.name.type === "JSXIdentifier" &&
|
|
19
|
+
path.value.name.name === "BoxNew") {
|
|
20
|
+
path.value.name.name = boxLocalName;
|
|
21
|
+
}
|
|
22
|
+
// Rename <Box.New ...> to <Box ...>
|
|
23
|
+
if (path.value.name.type === "JSXMemberExpression" &&
|
|
24
|
+
path.value.name.object.type === "JSXIdentifier" &&
|
|
25
|
+
path.value.name.object.name === boxLocalName &&
|
|
26
|
+
path.value.name.property.name === "New") {
|
|
27
|
+
path.value.name = j.jsxIdentifier(boxLocalName);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
root.find(j.JSXClosingElement).forEach((path) => {
|
|
31
|
+
if (path.value.name.type === "JSXIdentifier" &&
|
|
32
|
+
path.value.name.name === "BoxNew") {
|
|
33
|
+
path.value.name.name = boxLocalName;
|
|
34
|
+
}
|
|
35
|
+
if (path.value.name.type === "JSXMemberExpression" &&
|
|
36
|
+
path.value.name.object.type === "JSXIdentifier" &&
|
|
37
|
+
path.value.name.object.name === boxLocalName &&
|
|
38
|
+
path.value.name.property.name === "New") {
|
|
39
|
+
path.value.name = j.jsxIdentifier(boxLocalName);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
// Handle imports
|
|
43
|
+
const imports = root.find(j.ImportDeclaration).filter((path) => {
|
|
44
|
+
return (path.value.source.value === "@navikt/ds-react" ||
|
|
45
|
+
path.value.source.value === "@navikt/ds-react/Box");
|
|
46
|
+
});
|
|
47
|
+
imports.forEach((path) => {
|
|
48
|
+
const specifiers = path.value.specifiers;
|
|
49
|
+
if (!specifiers)
|
|
50
|
+
return;
|
|
51
|
+
const boxNewIndex = specifiers.findIndex((s) => s.type === "ImportSpecifier" && s.imported.name === "BoxNew");
|
|
52
|
+
if (boxNewIndex !== -1) {
|
|
53
|
+
const boxIndex = specifiers.findIndex((s) => s.type === "ImportSpecifier" && s.imported.name === "Box");
|
|
54
|
+
if (boxIndex !== -1) {
|
|
55
|
+
// Box already imported, remove BoxNew
|
|
56
|
+
const boxNewSpecifier = specifiers[boxNewIndex];
|
|
57
|
+
if (boxNewSpecifier.type === "ImportSpecifier" &&
|
|
58
|
+
boxNewSpecifier.local &&
|
|
59
|
+
boxNewSpecifier.local.name !== "BoxNew") {
|
|
60
|
+
const localName = boxNewSpecifier.local.name;
|
|
61
|
+
root.find(j.JSXOpeningElement).forEach((jsxPath) => {
|
|
62
|
+
if (jsxPath.value.name.type === "JSXIdentifier" &&
|
|
63
|
+
jsxPath.value.name.name === localName) {
|
|
64
|
+
jsxPath.value.name.name = boxLocalName;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
root.find(j.JSXClosingElement).forEach((jsxPath) => {
|
|
68
|
+
if (jsxPath.value.name.type === "JSXIdentifier" &&
|
|
69
|
+
jsxPath.value.name.name === localName) {
|
|
70
|
+
jsxPath.value.name.name = boxLocalName;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
specifiers.splice(boxNewIndex, 1);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Rename BoxNew to Box
|
|
78
|
+
const boxNewSpecifier = specifiers[boxNewIndex];
|
|
79
|
+
if (boxNewSpecifier.type === "ImportSpecifier") {
|
|
80
|
+
boxNewSpecifier.imported.name = "Box";
|
|
81
|
+
// If local name is BoxNew, rename it to Box
|
|
82
|
+
if (boxNewSpecifier.local &&
|
|
83
|
+
boxNewSpecifier.local.name === "BoxNew") {
|
|
84
|
+
boxNewSpecifier.local.name = "Box";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return root.toSource(toSourceOptions);
|
|
91
|
+
}
|