@xstate/codemod 0.1.0-beta.2 → 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.
@@ -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
- for (const configObj of findMachineConfigObjects(sourceFile)) {
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xstate/codemod",
3
- "version": "0.1.0-beta.2",
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.2"
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.