@astryxdesign/cli 0.6.3-canary.df1837b → 0.6.3-canary.e59d786
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/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +0 -4
- package/assets/codemods/transforms/next/index.mjs +0 -8
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +0 -1
- package/package.json +9 -9
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +0 -63
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +0 -148
package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs
CHANGED
|
@@ -81,7 +81,6 @@ describe('migrate-theme-catalog-to-descriptors', () => {
|
|
|
81
81
|
it('is staged for the next release as a project codemod', () => {
|
|
82
82
|
expect(manifest.map(t => [t.name, t.meta.codemodType])).toEqual([
|
|
83
83
|
['migrate-theme-catalog-to-descriptors', 'project'],
|
|
84
|
-
['migrate-native-picker-to-presentation', undefined],
|
|
85
84
|
]);
|
|
86
85
|
});
|
|
87
86
|
|
|
@@ -136,9 +135,6 @@ describe('migrate-theme-catalog-to-descriptors', () => {
|
|
|
136
135
|
|
|
137
136
|
it('previews without writing, even with no source folder', async () => {
|
|
138
137
|
writeKit([entry('ocean')]);
|
|
139
|
-
// A staged code codemod (migrate-native-picker-to-presentation) requires
|
|
140
|
-
// the source folder to exist; an empty one exercises the same preview.
|
|
141
|
-
fs.mkdirSync(path.join(root, 'src'), {recursive: true});
|
|
142
138
|
|
|
143
139
|
const result = await run(false, path.join(root, 'src'));
|
|
144
140
|
|
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
import migrateThemeCatalogToDescriptors, {
|
|
11
11
|
meta as migrateThemeCatalogToDescriptorsMeta,
|
|
12
12
|
} from './migrate-theme-catalog-to-descriptors.mjs';
|
|
13
|
-
import migrateNativePickerToPresentation, {
|
|
14
|
-
meta as migrateNativePickerToPresentationMeta,
|
|
15
|
-
} from './migrate-native-picker-to-presentation.mjs';
|
|
16
13
|
|
|
17
14
|
export default [
|
|
18
15
|
{
|
|
@@ -20,9 +17,4 @@ export default [
|
|
|
20
17
|
transform: migrateThemeCatalogToDescriptors,
|
|
21
18
|
meta: migrateThemeCatalogToDescriptorsMeta,
|
|
22
19
|
},
|
|
23
|
-
{
|
|
24
|
-
name: 'migrate-native-picker-to-presentation',
|
|
25
|
-
transform: migrateNativePickerToPresentation,
|
|
26
|
-
meta: migrateNativePickerToPresentationMeta,
|
|
27
|
-
},
|
|
28
20
|
];
|
|
@@ -17,7 +17,6 @@ export default function TimeInputConstrained() {
|
|
|
17
17
|
max={'22:00' as never}
|
|
18
18
|
description="Evening seating: 5 PM – 10 PM"
|
|
19
19
|
placeholder="Select reservation time"
|
|
20
|
-
presentation="adaptive-bottom-sheet"
|
|
21
20
|
value={evening as never}
|
|
22
21
|
onChange={setEvening as never}
|
|
23
22
|
hasClear
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.6.3-canary.
|
|
3
|
+
"version": "0.6.3-canary.e59d786",
|
|
4
4
|
"displayName": "CLI",
|
|
5
5
|
"description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -101,10 +101,10 @@
|
|
|
101
101
|
"zod": "^4.4.3"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
105
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
106
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
107
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
104
|
+
"@astryxdesign/charts": "0.6.3-canary.e59d786",
|
|
105
|
+
"@astryxdesign/core": "0.6.3-canary.e59d786",
|
|
106
|
+
"@astryxdesign/lab": "0.6.3-canary.e59d786",
|
|
107
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.e59d786"
|
|
108
108
|
},
|
|
109
109
|
"peerDependenciesMeta": {
|
|
110
110
|
"@astryxdesign/charts": {
|
|
@@ -121,10 +121,10 @@
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
125
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
126
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
127
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
124
|
+
"@astryxdesign/charts": "0.6.3-canary.e59d786",
|
|
125
|
+
"@astryxdesign/core": "0.6.3-canary.e59d786",
|
|
126
|
+
"@astryxdesign/lab": "0.6.3-canary.e59d786",
|
|
127
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.e59d786",
|
|
128
128
|
"@heroicons/react": "^2.2.0",
|
|
129
129
|
"@stylexjs/stylex": "^0.19.0",
|
|
130
130
|
"@types/babel__core": "^7.20.5",
|
package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
import {describe, expect, it} from 'vitest';
|
|
4
|
-
import transform from '../migrate-native-picker-to-presentation.mjs';
|
|
5
|
-
|
|
6
|
-
async function applyTransform(source) {
|
|
7
|
-
const jscodeshift = (await import('jscodeshift')).default;
|
|
8
|
-
const j = jscodeshift.withParser('tsx');
|
|
9
|
-
const api = {jscodeshift: j, stats: () => {}, report: () => {}};
|
|
10
|
-
return transform({source, path: 'test.tsx'}, api) ?? source;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
describe('migrate-native-picker-to-presentation', () => {
|
|
14
|
-
it('maps DateInput and DateTimeInput values (FR3)', async () => {
|
|
15
|
-
const output =
|
|
16
|
-
await applyTransform(`import {DateInput, DateTimeInput} from '@astryxdesign/core';
|
|
17
|
-
const a = <DateInput label="d" nativePicker="touch" />;
|
|
18
|
-
const b = <DateInput label="d" nativePicker="always" />;
|
|
19
|
-
const c = <DateTimeInput label="dt" nativePicker="never" />;`);
|
|
20
|
-
|
|
21
|
-
expect(output).toContain("presentation='adaptive-native'");
|
|
22
|
-
expect(output).toContain("presentation='native'");
|
|
23
|
-
expect(output).toContain("presentation='adaptive-bottom-sheet'");
|
|
24
|
-
expect(output).not.toContain('nativePicker');
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('maps TimeInput never to text-input (FR3)', async () => {
|
|
28
|
-
const output =
|
|
29
|
-
await applyTransform(`import {TimeInput} from '@astryxdesign/core';
|
|
30
|
-
const a = <TimeInput label="t" nativePicker="never" />;
|
|
31
|
-
const b = <TimeInput label="t" nativePicker={'touch'} />;`);
|
|
32
|
-
|
|
33
|
-
expect(output).toContain("presentation='text-input'");
|
|
34
|
-
expect(output).toContain("presentation={'adaptive-native'}");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('drops nativePicker when presentation is already set (FR4)', async () => {
|
|
38
|
-
const output =
|
|
39
|
-
await applyTransform(`import {DateInput} from '@astryxdesign/core';
|
|
40
|
-
const a = <DateInput label="d" presentation="popover" nativePicker="always" />;`);
|
|
41
|
-
|
|
42
|
-
expect(output).toContain('presentation="popover"');
|
|
43
|
-
expect(output).not.toContain('nativePicker');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('leaves dynamic values and unrelated components unchanged', async () => {
|
|
47
|
-
const source = `import {DateInput, Selector} from '@astryxdesign/core';
|
|
48
|
-
const a = <DateInput label="d" nativePicker={mode} />;
|
|
49
|
-
const b = <Selector nativePicker="never" />;`;
|
|
50
|
-
expect(await applyTransform(source)).toBe(source);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('leaves a mixed static/dynamic conditional byte-identical when a sibling migrates', async () => {
|
|
54
|
-
const output =
|
|
55
|
-
await applyTransform(`import {TimeInput} from '@astryxdesign/core';
|
|
56
|
-
const a = <TimeInput label="t" nativePicker="touch" />;
|
|
57
|
-
const b = <TimeInput label="t" nativePicker={flag ? 'always' : mode} />;`);
|
|
58
|
-
|
|
59
|
-
expect(output).toContain("presentation='adaptive-native'");
|
|
60
|
-
expect(output).toContain("nativePicker={flag ? 'always' : mode}");
|
|
61
|
-
expect(output).not.toContain("'native'");
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Codemod: migrate nativePicker to presentation on date/time inputs
|
|
5
|
-
*
|
|
6
|
-
* `spec:AST-043` FR3 mapping, applied only to static literals written
|
|
7
|
-
* directly on imported `DateInput`, `DateTimeInput`, and `TimeInput`
|
|
8
|
-
* elements: the prop is renamed to `presentation` and its value mapped.
|
|
9
|
-
* When the element already sets `presentation`, the deprecated prop is
|
|
10
|
-
* removed (presentation wins, FR4). Dynamic values are left unchanged —
|
|
11
|
-
* the deprecated prop keeps working, so an unmigrated callsite is still
|
|
12
|
-
* correct, and guessing at an expression's values would not be.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import {transformProp} from '../../transform-prop.mjs';
|
|
16
|
-
|
|
17
|
-
export const meta = {
|
|
18
|
-
title: 'Migrate nativePicker to presentation',
|
|
19
|
-
description:
|
|
20
|
-
'Renames `nativePicker` to `presentation` on DateInput, DateTimeInput, ' +
|
|
21
|
-
'and TimeInput, mapping touch→adaptive-native, always→native, and ' +
|
|
22
|
-
'never→adaptive-bottom-sheet (text-input for TimeInput). Dynamic ' +
|
|
23
|
-
'values are left for manual migration; the deprecated prop still works.',
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const CORE_IMPORT_RE = /^@(astryxdesign|xds)\/core(?:\/|$)/;
|
|
27
|
-
|
|
28
|
-
const COMPONENT_PROPS = new Map([
|
|
29
|
-
['DateInput', new Set(['nativePicker'])],
|
|
30
|
-
['DateTimeInput', new Set(['nativePicker'])],
|
|
31
|
-
['TimeInput', new Set(['nativePicker'])],
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
/** @param {string} component @param {string} value */
|
|
35
|
-
function mapValue(component, value) {
|
|
36
|
-
switch (value) {
|
|
37
|
-
case 'touch':
|
|
38
|
-
return 'adaptive-native';
|
|
39
|
-
case 'always':
|
|
40
|
-
return 'native';
|
|
41
|
-
case 'never':
|
|
42
|
-
return component === 'TimeInput' ? 'text-input' : 'adaptive-bottom-sheet';
|
|
43
|
-
default:
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Collect the string-literal leaves of a value expression without mutating
|
|
50
|
-
* anything. Returns false for any dynamic or non-string node.
|
|
51
|
-
* @param {any} node
|
|
52
|
-
* @param {any[]} leaves
|
|
53
|
-
* @returns {boolean}
|
|
54
|
-
*/
|
|
55
|
-
function collectStaticLeaves(node, leaves) {
|
|
56
|
-
if (!node) return false;
|
|
57
|
-
if (
|
|
58
|
-
node.type === 'TSAsExpression' ||
|
|
59
|
-
node.type === 'TSSatisfiesExpression' ||
|
|
60
|
-
node.type === 'TypeCastExpression' ||
|
|
61
|
-
node.type === 'ParenthesizedExpression'
|
|
62
|
-
) {
|
|
63
|
-
return collectStaticLeaves(node.expression, leaves);
|
|
64
|
-
}
|
|
65
|
-
if (node.type === 'ConditionalExpression') {
|
|
66
|
-
return (
|
|
67
|
-
collectStaticLeaves(node.consequent, leaves) &&
|
|
68
|
-
collectStaticLeaves(node.alternate, leaves)
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
if (
|
|
72
|
-
(node.type !== 'StringLiteral' && node.type !== 'Literal') ||
|
|
73
|
-
typeof node.value !== 'string'
|
|
74
|
-
) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
leaves.push(node);
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Map every leaf, or none of them: a mixed static/dynamic conditional must
|
|
83
|
-
* stay byte-identical, never half-migrated.
|
|
84
|
-
* @param {any} node
|
|
85
|
-
* @param {string} component
|
|
86
|
-
*/
|
|
87
|
-
function mapStaticValue(node, component) {
|
|
88
|
-
/** @type {any[]} */
|
|
89
|
-
const leaves = [];
|
|
90
|
-
if (!collectStaticLeaves(node, leaves)) return false;
|
|
91
|
-
if (leaves.some(leaf => mapValue(component, leaf.value) === undefined)) {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
for (const leaf of leaves) {
|
|
95
|
-
leaf.value = mapValue(component, leaf.value);
|
|
96
|
-
if (leaf.raw) leaf.raw = undefined;
|
|
97
|
-
}
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @param {import('../../../../authoring/codemod/type').AstryxCodemodFile} file
|
|
103
|
-
* @param {import('../../../../authoring/codemod/type').CodemodTransformApi} api
|
|
104
|
-
* @returns {string | null | undefined}
|
|
105
|
-
*/
|
|
106
|
-
export default function transformer(file, api) {
|
|
107
|
-
if (!file.source.includes('nativePicker')) return undefined;
|
|
108
|
-
const j = api.jscodeshift;
|
|
109
|
-
const root = j(file.source);
|
|
110
|
-
let hasChanges = false;
|
|
111
|
-
|
|
112
|
-
transformProp(
|
|
113
|
-
root,
|
|
114
|
-
j,
|
|
115
|
-
{
|
|
116
|
-
matchesImport: source => CORE_IMPORT_RE.test(source),
|
|
117
|
-
components: COMPONENT_PROPS,
|
|
118
|
-
},
|
|
119
|
-
(propPath, {component}) => {
|
|
120
|
-
const opening = propPath.parent?.node;
|
|
121
|
-
const attributes = opening?.attributes ?? [];
|
|
122
|
-
const hasPresentation = attributes.some(
|
|
123
|
-
(/** @type {any} */ attribute) =>
|
|
124
|
-
attribute.type === 'JSXAttribute' &&
|
|
125
|
-
attribute.name?.name === 'presentation',
|
|
126
|
-
);
|
|
127
|
-
const prop = propPath.node;
|
|
128
|
-
if (hasPresentation) {
|
|
129
|
-
// FR4: presentation wins; drop the deprecated prop.
|
|
130
|
-
opening.attributes = attributes.filter(
|
|
131
|
-
(/** @type {any} */ attribute) => attribute !== prop,
|
|
132
|
-
);
|
|
133
|
-
hasChanges = true;
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const value =
|
|
137
|
-
prop.value?.type === 'JSXExpressionContainer'
|
|
138
|
-
? prop.value.expression
|
|
139
|
-
: prop.value;
|
|
140
|
-
if (!mapStaticValue(value, component)) return;
|
|
141
|
-
prop.name.name = 'presentation';
|
|
142
|
-
hasChanges = true;
|
|
143
|
-
},
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
if (!hasChanges) return undefined;
|
|
147
|
-
return root.toSource({quote: 'single'});
|
|
148
|
-
}
|