@xstate/codemod 0.1.0-beta.1 → 0.1.0-beta.3
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
CHANGED
|
@@ -9,3 +9,5 @@ The transforms rename imports, wrap string targets, convert inline `types` decla
|
|
|
9
9
|
|
|
10
10
|
<!-- helper binding and output validation from src/util.ts, src/transforms/types-to-schemas.ts and src/runner.ts -->
|
|
11
11
|
The codemod supports named, namespace and type-only imports. It checks transformed syntax before saving. Run your application's typecheck and tests after migration, and review any reported manual migration steps.
|
|
12
|
+
|
|
13
|
+
The `string-targets` transform also wraps inline `xstate/fsm` targets in `on` and `always`, including `setup(...).createFSM` and aliased `createFSM` imports. It preserves string `initial` values. Review separately stored configurations and string-returning transition functions manually.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Transform } from "../types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Converts bare string transition values inside `createMachine`/`setup().
|
|
4
|
-
* createMachine`/`createStateConfig` config objects into `{ target: '...' }`.
|
|
4
|
+
* createMachine`/`createStateConfig`/`createFSM` config objects into `{ target: '...' }`.
|
|
5
5
|
*
|
|
6
6
|
* Does NOT touch `initial:` (still a string in v6) or existing `target:`
|
|
7
7
|
* values.
|
package/dist/xstate-codemod.js
CHANGED
|
@@ -165,7 +165,7 @@ const DIRECT_TRANSITION_KEYS = new Set(['onDone', 'onError', 'always']);
|
|
|
165
165
|
* Returns true if a change was made.
|
|
166
166
|
*/
|
|
167
167
|
function wrapValue(node) {
|
|
168
|
-
if (Node.isStringLiteral(node)) {
|
|
168
|
+
if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
169
169
|
const raw = node.getText(); // includes quotes
|
|
170
170
|
node.replaceWithText(`{ target: ${raw} }`);
|
|
171
171
|
return true;
|
|
@@ -175,7 +175,7 @@ function wrapValue(node) {
|
|
|
175
175
|
// Iterate over a snapshot; replacing elements is index-stable here since
|
|
176
176
|
// we replace text in place without adding/removing elements.
|
|
177
177
|
for (const el of node.getElements()) {
|
|
178
|
-
if (Node.isStringLiteral(el)) {
|
|
178
|
+
if (Node.isStringLiteral(el) || Node.isNoSubstitutionTemplateLiteral(el)) {
|
|
179
179
|
el.replaceWithText(`{ target: ${el.getText()} }`);
|
|
180
180
|
changed = true;
|
|
181
181
|
}
|
|
@@ -267,18 +267,29 @@ function getKey$1(prop) {
|
|
|
267
267
|
|
|
268
268
|
/**
|
|
269
269
|
* Converts bare string transition values inside `createMachine`/`setup().
|
|
270
|
-
* createMachine`/`createStateConfig` config objects into `{ target: '...' }`.
|
|
270
|
+
* createMachine`/`createStateConfig`/`createFSM` config objects into `{ target: '...' }`.
|
|
271
271
|
*
|
|
272
272
|
* Does NOT touch `initial:` (still a string in v6) or existing `target:`
|
|
273
273
|
* values.
|
|
274
274
|
*/
|
|
275
275
|
const stringTargets = {
|
|
276
276
|
name: 'string-targets',
|
|
277
|
-
description: "Wrap bare string transition values (on/after/onDone/onError/always) into { target: '...' } inside machine config objects. Best-effort: matches createMachine/createStateConfig by call name.",
|
|
277
|
+
description: "Wrap bare string transition values (on/after/onDone/onError/always) into { target: '...' } inside machine config objects. Best-effort: matches createMachine/createStateConfig/createFSM by call name.",
|
|
278
278
|
apply(sourceFile) {
|
|
279
279
|
const notes = [];
|
|
280
280
|
let total = 0;
|
|
281
|
-
|
|
281
|
+
const callNames = ['createMachine', 'createStateConfig', 'createFSM'];
|
|
282
|
+
for (const declaration of sourceFile.getImportDeclarations()) {
|
|
283
|
+
if (declaration.getModuleSpecifierValue() !== 'xstate/fsm') {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
for (const specifier of declaration.getNamedImports()) {
|
|
287
|
+
if (specifier.getName() === 'createFSM') {
|
|
288
|
+
callNames.push(specifier.getAliasNode()?.getText() ?? 'createFSM');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const configObj of findMachineConfigObjects(sourceFile, callNames)) {
|
|
282
293
|
total += walkStateNode(configObj, notes);
|
|
283
294
|
}
|
|
284
295
|
return {
|
|
@@ -3567,7 +3578,7 @@ function toJson(value, stats, seen = new Set(), maxDepth = Infinity) {
|
|
|
3567
3578
|
if (value === null) return null;
|
|
3568
3579
|
const obj = value;
|
|
3569
3580
|
if (isActorRef(obj)) return {
|
|
3570
|
-
|
|
3581
|
+
'@actor': normalizeId(obj.id)
|
|
3571
3582
|
};
|
|
3572
3583
|
if (obj instanceof Error) return String(obj);
|
|
3573
3584
|
if (typeof obj.toJSON === 'function') return toJson(obj.toJSON(), stats, seen, maxDepth);
|
|
@@ -3667,7 +3678,7 @@ function mapDeep(value, fn) {
|
|
|
3667
3678
|
return value;
|
|
3668
3679
|
}
|
|
3669
3680
|
const stripAnonSuffix = value => mapDeep(value, (key, item) => (key === 'id' || key === 'to') && typeof item === 'string' ? item.replace(/(:\d+|\[\d+\])$/, '').replace(/^(x:\d+|\d+\.)/, '') : item);
|
|
3670
|
-
const isActorMarker = item => !!item && typeof item === 'object' && '
|
|
3681
|
+
const isActorMarker = item => !!item && typeof item === 'object' && '@actor' in item;
|
|
3671
3682
|
const stripErrorPrefix = message => message.replace(/^(\w*Error:\s*)+/, '').trim();
|
|
3672
3683
|
const INTENTIONAL_DELTAS = [{
|
|
3673
3684
|
rule: 'anonymous-child-id',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xstate/codemod",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.3",
|
|
4
4
|
"description": "Codemods for migrating XState source between versions (v5 → v6)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"xstate",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"ts-morph": "^24.0.0",
|
|
37
37
|
"tsx": "^4.23.13",
|
|
38
38
|
"xstate5": "npm:xstate@^5.33.0",
|
|
39
|
-
"xstate": "^6.0.0-beta.
|
|
39
|
+
"xstate": "^6.0.0-beta.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"vitest": "^3.2.2"
|
|
@@ -50,3 +50,5 @@ Rules:
|
|
|
50
50
|
- Never widen `--compare` to make a diff disappear.
|
|
51
51
|
- Report every `unstubbed` entry to the user. Inline actor logic runs for real and is not stubbed.
|
|
52
52
|
- Stop and ask the user after 5 repair rounds without exit 0.
|
|
53
|
+
|
|
54
|
+
The `string-targets` transform also wraps inline `xstate/fsm` targets in `on` and `always`, including `setup(...).createFSM` and aliased `createFSM` imports. It preserves string `initial` values. Review separately stored configurations and string-returning transition functions manually.
|