diff --git a/.changeset/shiny-seals-rush.md b/.changeset/shiny-seals-rush.md
new file mode 100644
index 0000000..729b66d
--- /dev/null
+++ b/.changeset/shiny-seals-rush.md
@@ -0,0 +1,7 @@
+---
+"@effect/tsgo": patch
+---
+
+Fix the toggle-pipe-style refactor to avoid formatter panics on nested callback bodies such as SQL effects using `.pipe(Effect.flatMap(...))`.
+
+This adds a regression test and updates the affected refactor baselines to match the new text-preserving rewrite output.
diff --git a/internal/refactors/toggle_pipe_style.go b/internal/refactors/toggle_pipe_style.go
index 9f91caa..be2b84e 100644
--- a/internal/refactors/toggle_pipe_style.go
+++ b/internal/refactors/toggle_pipe_style.go
@@ -1,12 +1,16 @@
package refactors
import (
+ "strings"
+
"github.com/effect-ts/tsgo/internal/refactor"
"github.com/effect-ts/tsgo/internal/typeparser"
"github.com/microsoft/typescript-go/shim/ast"
"github.com/microsoft/typescript-go/shim/astnav"
"github.com/microsoft/typescript-go/shim/ls"
"github.com/microsoft/typescript-go/shim/ls/change"
+ "github.com/microsoft/typescript-go/shim/lsp/lsproto"
+ "github.com/microsoft/typescript-go/shim/scanner"
)
var TogglePipeStyle = refactor.Refactor{
@@ -45,17 +49,12 @@ func runTogglePipeStyle(ctx *refactor.Context) []ls.CodeAction {
action := ctx.NewRefactorAction(refactor.RefactorAction{
Description: "Rewrite as X.pipe(Y, Z, ...)",
Run: func(tracker *change.Tracker) {
- clonedSubject := tracker.DeepCloneNode(pipeCall.Subject)
- pipeAccess := tracker.NewPropertyAccessExpression(clonedSubject, nil, tracker.NewIdentifier("pipe"), ast.NodeFlagsNone)
-
- var clonedArgs []*ast.Node
- for _, arg := range pipeCall.Args {
- clonedArgs = append(clonedArgs, tracker.DeepCloneNode(arg))
- }
-
- callExpr := tracker.NewCallExpression(pipeAccess, nil, nil, tracker.NewNodeList(clonedArgs), ast.NodeFlagsNone)
- ast.SetParentInChildren(callExpr)
- tracker.ReplaceNode(ctx.SourceFile, node, callExpr, nil)
+ start := astnav.GetStartOfNode(node, ctx.SourceFile, false)
+ rewritten := togglePipeToMethodText(ctx.SourceFile, pipeCall.Subject, pipeCall.Args)
+ tracker.ReplaceRangeWithText(ctx.SourceFile, lsproto.Range{
+ Start: ctx.BytePosToLSPPosition(start),
+ End: ctx.BytePosToLSPPosition(node.End()),
+ }, rewritten)
},
})
if action == nil {
@@ -69,18 +68,12 @@ func runTogglePipeStyle(ctx *refactor.Context) []ls.CodeAction {
action := ctx.NewRefactorAction(refactor.RefactorAction{
Description: "Rewrite as pipe(X, Y, Z, ...)",
Run: func(tracker *change.Tracker) {
- clonedSubject := tracker.DeepCloneNode(pipeCall.Subject)
-
- allArgs := make([]*ast.Node, 0, 1+len(pipeCall.Args))
- allArgs = append(allArgs, clonedSubject)
- for _, arg := range pipeCall.Args {
- allArgs = append(allArgs, tracker.DeepCloneNode(arg))
- }
-
- pipeId := tracker.NewIdentifier("pipe")
- callExpr := tracker.NewCallExpression(pipeId, nil, nil, tracker.NewNodeList(allArgs), ast.NodeFlagsNone)
- ast.SetParentInChildren(callExpr)
- tracker.ReplaceNode(ctx.SourceFile, node, callExpr, nil)
+ start := astnav.GetStartOfNode(node, ctx.SourceFile, false)
+ rewritten := togglePipeToFunctionText(ctx.SourceFile, pipeCall.Subject, pipeCall.Args)
+ tracker.ReplaceRangeWithText(ctx.SourceFile, lsproto.Range{
+ Start: ctx.BytePosToLSPPosition(start),
+ End: ctx.BytePosToLSPPosition(node.End()),
+ }, rewritten)
},
})
if action == nil {
@@ -93,3 +86,20 @@ func runTogglePipeStyle(ctx *refactor.Context) []ls.CodeAction {
return nil
}
+
+func togglePipeToMethodText(sf *ast.SourceFile, subject *ast.Node, args []*ast.Node) string {
+ parts := make([]string, 0, len(args))
+ for _, arg := range args {
+ parts = append(parts, scanner.GetSourceTextOfNodeFromSourceFile(sf, arg, false))
+ }
+ return scanner.GetSourceTextOfNodeFromSourceFile(sf, subject, false) + ".pipe(" + strings.Join(parts, ", ") + ")"
+}
+
+func togglePipeToFunctionText(sf *ast.SourceFile, subject *ast.Node, args []*ast.Node) string {
+ parts := make([]string, 0, len(args)+1)
+ parts = append(parts, scanner.GetSourceTextOfNodeFromSourceFile(sf, subject, false))
+ for _, arg := range args {
+ parts = append(parts, scanner.GetSourceTextOfNodeFromSourceFile(sf, arg, false))
+ }
+ return "pipe(" + strings.Join(parts, ", ") + ")"
+}
diff --git a/testdata/baselines/reference/effect-v3/effectGenToFn.refactors.txt b/testdata/baselines/reference/effect-v3/effectGenToFn.refactors.txt
index 6e3c0b8..b269603 100644
--- a/testdata/baselines/reference/effect-v3/effectGenToFn.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/effectGenToFn.refactors.txt
@@ -124,10 +124,10 @@ export const program = () =>
export const programWithPipes = (fa: number, fb: number) =>
pipe(Eff.gen(function*() {
- const a = yield* Eff.succeed(fa)
- const b = yield* Eff.succeed(fb)
- return a + b
- }), Eff.map(a => a + 1))
+ const a = yield* Eff.succeed(fa)
+ const b = yield* Eff.succeed(fb)
+ return a + b
+ }), Eff.map((a) => a + 1))
export function sampleReturns(arg1: A, arg2: B) {
return Eff.gen(function*() {
diff --git a/testdata/baselines/reference/effect-v3/effectGenToFn_mixedPipes.refactors.txt b/testdata/baselines/reference/effect-v3/effectGenToFn_mixedPipes.refactors.txt
index 23eb6f6..83b6518 100644
--- a/testdata/baselines/reference/effect-v3/effectGenToFn_mixedPipes.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/effectGenToFn_mixedPipes.refactors.txt
@@ -22,9 +22,9 @@ import { pipe } from "effect/Function"
const test = () =>
pipe(
pipe(Effect.gen(function*() {
- const test = "test"
- return yield* Effect.succeed(test)
- }), Effect.asVoid),
+ const test = "test"
+ return yield* Effect.succeed(test)
+ }), Effect.asVoid),
Effect.tapError(Effect.logError)
)
diff --git a/testdata/baselines/reference/effect-v3/effectGenToFn_withPipes.refactors.txt b/testdata/baselines/reference/effect-v3/effectGenToFn_withPipes.refactors.txt
index eb3b2ee..bef1640 100644
--- a/testdata/baselines/reference/effect-v3/effectGenToFn_withPipes.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/effectGenToFn_withPipes.refactors.txt
@@ -21,8 +21,8 @@ import { pipe } from "effect/Function"
const test = () =>
Effect.gen(function*() {
- const test = "test"
- return yield* Effect.succeed(test)
+ const test = "test"
+ return yield* Effect.succeed(test)
}).pipe(Effect.tapError(Effect.logError))
diff --git a/testdata/baselines/reference/effect-v3/pipeableToDatafirst.refactors.txt b/testdata/baselines/reference/effect-v3/pipeableToDatafirst.refactors.txt
index 705cf3a..6f9ceee 100644
--- a/testdata/baselines/reference/effect-v3/pipeableToDatafirst.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/pipeableToDatafirst.refactors.txt
@@ -63,7 +63,7 @@ const test3 = pipe(
import * as T from "effect/Effect"
import { pipe } from "effect/Function"
-const test = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), T.zipRight(T.succeed(42)), T.map(_ => _ * 2))
+const test = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), T.zipRight(T.succeed(42)), T.map((_) => _ * 2))
const noDataFirst = (value: string) => (eff: T.Effect) => pipe(eff, T.zipLeft(T.log(value)))
@@ -190,7 +190,7 @@ const test = pipe(
const noDataFirst = (value: string) => (eff: T.Effect) => pipe(eff, T.zipLeft(T.log(value)))
-const test2 = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), noDataFirst("42"))
+const test2 = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), noDataFirst("42"))
const test3 = pipe(
T.succeed("Hello"),
@@ -316,7 +316,7 @@ const test2 = pipe(
noDataFirst("42")
)
-const test3 = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), noDataFirst("a"), noDataFirst("b"), noDataFirst("c"))
+const test3 = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), noDataFirst("a"), noDataFirst("b"), noDataFirst("c"))
=== [R3] Refactor 2: "Rewrite to datafirst" ===
diff --git a/testdata/baselines/reference/effect-v3/togglePipeStyle.refactors.txt b/testdata/baselines/reference/effect-v3/togglePipeStyle.refactors.txt
index 0dfa465..336e46d 100644
--- a/testdata/baselines/reference/effect-v3/togglePipeStyle.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/togglePipeStyle.refactors.txt
@@ -36,7 +36,7 @@ export const toPipeable = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
import * as Effect from "effect/Effect"
import { pipe } from "effect/Function"
-export const toRegularPipe = pipe(Effect.succeed(42), Effect.map(x => x * 2))
+export const toRegularPipe = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
export const toPipeable = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
@@ -77,7 +77,7 @@ import { pipe } from "effect/Function"
export const toRegularPipe = Effect.succeed(42).pipe(Effect.map((x) => x * 2))
-export const toPipeable = Effect.succeed(42).pipe(Effect.map(x => x * 2))
+export const toPipeable = Effect.succeed(42).pipe(Effect.map((x) => x * 2))
=== [R2] Refactor 2: "Wrap with Effect.gen" ===
diff --git a/testdata/baselines/reference/effect-v3/wrapWithEffectGen.refactors.txt b/testdata/baselines/reference/effect-v3/wrapWithEffectGen.refactors.txt
index 7d3a5ce..40ec584 100644
--- a/testdata/baselines/reference/effect-v3/wrapWithEffectGen.refactors.txt
+++ b/testdata/baselines/reference/effect-v3/wrapWithEffectGen.refactors.txt
@@ -166,7 +166,7 @@ export const test1 = Effect.succeed(42)
export const test3 = test1
-export const test2 = pipe(Effect.succeed(42), Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test2 = pipe(Effect.succeed(42), Effect.map((n) => n + 1), Effect.map((n) => n - 1))
export const test4 = pipe(
Effect.succeed(42),
@@ -235,7 +235,7 @@ export const test1 = Effect.succeed(42)
export const test3 = test1
-export const test2 = pipe(Effect.succeed(42), Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test2 = pipe(Effect.succeed(42), Effect.map((n) => n + 1), Effect.map((n) => n - 1))
export const test4 = pipe(
Effect.succeed(42),
@@ -309,7 +309,7 @@ export const test2 = Effect.succeed(42).pipe(
Effect.map((n) => n - 1)
)
-export const test4 = Effect.succeed(42).pipe(Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test4 = Effect.succeed(42).pipe(Effect.map((n) => n + 1), Effect.map((n) => n - 1))
=== [R5] Refactor 2: "Rewrite to datafirst" ===
@@ -397,7 +397,7 @@ export const test2 = Effect.succeed(42).pipe(
Effect.map((n) => n - 1)
)
-export const test4 = Effect.succeed(42).pipe(Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test4 = Effect.succeed(42).pipe(Effect.map((n) => n + 1), Effect.map((n) => n - 1))
=== [R6] Refactor 2: "Wrap with Effect.gen" ===
diff --git a/testdata/baselines/reference/effect-v4/effectGenToFn.refactors.txt b/testdata/baselines/reference/effect-v4/effectGenToFn.refactors.txt
index bf40975..01bd080 100644
--- a/testdata/baselines/reference/effect-v4/effectGenToFn.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/effectGenToFn.refactors.txt
@@ -121,10 +121,10 @@ export const program = () =>
export const programWithPipes = (fa: number, fb: number) =>
pipe(Eff.gen(function*() {
- const a = yield* Eff.succeed(fa)
- const b = yield* Eff.succeed(fb)
- return a + b
- }), Eff.map(a => a + 1))
+ const a = yield* Eff.succeed(fa)
+ const b = yield* Eff.succeed(fb)
+ return a + b
+ }), Eff.map((a) => a + 1))
export function sampleReturns(arg1: A, arg2: B) {
return Eff.gen(function*() {
diff --git a/testdata/baselines/reference/effect-v4/effectGenToFn_mixedPipes.refactors.txt b/testdata/baselines/reference/effect-v4/effectGenToFn_mixedPipes.refactors.txt
index c366b09..ac094fe 100644
--- a/testdata/baselines/reference/effect-v4/effectGenToFn_mixedPipes.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/effectGenToFn_mixedPipes.refactors.txt
@@ -21,9 +21,9 @@ import { pipe } from "effect/Function"
const test = () =>
pipe(
pipe(Effect.gen(function*() {
- const test = "test"
- return yield* Effect.succeed(test)
- }), Effect.asVoid),
+ const test = "test"
+ return yield* Effect.succeed(test)
+ }), Effect.asVoid),
Effect.tapError(Effect.logError)
)
diff --git a/testdata/baselines/reference/effect-v4/effectGenToFn_withPipes.refactors.txt b/testdata/baselines/reference/effect-v4/effectGenToFn_withPipes.refactors.txt
index 3bcc3e1..98b873a 100644
--- a/testdata/baselines/reference/effect-v4/effectGenToFn_withPipes.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/effectGenToFn_withPipes.refactors.txt
@@ -20,8 +20,8 @@ import { pipe } from "effect/Function"
const test = () =>
Effect.gen(function*() {
- const test = "test"
- return yield* Effect.succeed(test)
+ const test = "test"
+ return yield* Effect.succeed(test)
}).pipe(Effect.tapError(Effect.logError))
diff --git a/testdata/baselines/reference/effect-v4/pipeableToDatafirst.refactors.txt b/testdata/baselines/reference/effect-v4/pipeableToDatafirst.refactors.txt
index 5398c0a..72171a0 100644
--- a/testdata/baselines/reference/effect-v4/pipeableToDatafirst.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/pipeableToDatafirst.refactors.txt
@@ -61,7 +61,7 @@ const test3 = pipe(
import * as T from "effect/Effect"
import { pipe } from "effect/Function"
-const test = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), T.andThen(T.succeed(42)), T.map(_ => _ * 2))
+const test = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), T.andThen(T.succeed(42)), T.map((_) => _ * 2))
const noDataFirst = (value: string) => (eff: T.Effect) => pipe(eff, T.andThen(T.log(value)))
@@ -184,7 +184,7 @@ const test = pipe(
const noDataFirst = (value: string) => (eff: T.Effect) => pipe(eff, T.andThen(T.log(value)))
-const test2 = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), noDataFirst("42"))
+const test2 = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), noDataFirst("42"))
const test3 = pipe(
T.succeed("Hello"),
@@ -306,7 +306,7 @@ const test2 = pipe(
noDataFirst("42")
)
-const test3 = T.succeed("Hello").pipe(T.flatMap(_ => T.log(_)), noDataFirst("a"), noDataFirst("b"), noDataFirst("c"))
+const test3 = T.succeed("Hello").pipe(T.flatMap((_) => T.log(_)), noDataFirst("a"), noDataFirst("b"), noDataFirst("c"))
=== [R3] Refactor 2: "Rewrite to datafirst" ===
diff --git a/testdata/baselines/reference/effect-v4/togglePipeStyle.refactors.txt b/testdata/baselines/reference/effect-v4/togglePipeStyle.refactors.txt
index 9580629..9410316 100644
--- a/testdata/baselines/reference/effect-v4/togglePipeStyle.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/togglePipeStyle.refactors.txt
@@ -34,7 +34,7 @@ export const toPipeable = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
import * as Effect from "effect/Effect"
import { pipe } from "effect/Function"
-export const toRegularPipe = pipe(Effect.succeed(42), Effect.map(x => x * 2))
+export const toRegularPipe = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
export const toPipeable = pipe(Effect.succeed(42), Effect.map((x) => x * 2))
@@ -72,7 +72,7 @@ import { pipe } from "effect/Function"
export const toRegularPipe = Effect.succeed(42).pipe(Effect.map((x) => x * 2))
-export const toPipeable = Effect.succeed(42).pipe(Effect.map(x => x * 2))
+export const toPipeable = Effect.succeed(42).pipe(Effect.map((x) => x * 2))
=== [R2] Refactor 2: "Wrap with Effect.gen" ===
diff --git a/testdata/baselines/reference/effect-v4/togglePipeStyle_nestedCallback.refactors.txt b/testdata/baselines/reference/effect-v4/togglePipeStyle_nestedCallback.refactors.txt
new file mode 100644
index 0000000..734de2b
--- /dev/null
+++ b/testdata/baselines/reference/effect-v4/togglePipeStyle_nestedCallback.refactors.txt
@@ -0,0 +1,108 @@
+=== Refactor Inventory ===
+
+[R1] selection: "11:9-11:10"
+ Refactor 0: "Wrap with pipe" (refactor.rewrite.effect.wrapWithPipe)
+ Refactor 1: "Rewrite as pipe(X, Y, Z, ...)" (refactor.rewrite.effect.togglePipeStyle)
+ Refactor 2: "Wrap with Effect.gen" (refactor.rewrite.effect.wrapWithEffectGen)
+ Refactor 3: "Toggle return type annotation" (refactor.rewrite.effect.toggleReturnTypeAnnotation)
+
+[R2] selection: "empty (0:0-0:0)"
+ (no refactors)
+
+=== Refactor Application Results ===
+
+=== [R1] Refactor 0: "Wrap with pipe" ===
+
+--- file:///.src/togglePipeStyle_nestedCallback.ts ---
+// refactor: 11:9-11:10
+import * as Effect from "effect/Effect"
+
+type SqlResult = ReadonlyArray<{ id: number }>
+
+const sql = (_strings: TemplateStringsArray, ..._args: ReadonlyArray): Effect.Effect =>
+ Effect.succeed([])
+
+export const insertEnvelope = {
+ pg: () => (_row: { id: string }, messageId: string) =>
+ sql`pipe(
+) select * from messages where id = ${messageId}
+ `.pipe(Effect.flatMap((rows) => {
+ if (rows.length > 0) return Effect.succeed(rows)
+ return sql`
+ select * from messages where id = ${messageId}
+ `
+ }))
+}
+
+
+=== [R1] Refactor 1: "Rewrite as pipe(X, Y, Z, ...)" ===
+
+--- file:///.src/togglePipeStyle_nestedCallback.ts ---
+// refactor: 11:9-11:10
+import * as Effect from "effect/Effect"
+
+type SqlResult = ReadonlyArray<{ id: number }>
+
+const sql = (_strings: TemplateStringsArray, ..._args: ReadonlyArray): Effect.Effect =>
+ Effect.succeed([])
+
+export const insertEnvelope = {
+ pg: () => (_row: { id: string }, messageId: string) =>
+ pipe(sql`
+ select * from messages where id = ${messageId}
+ `, Effect.flatMap((rows) => {
+ if (rows.length > 0) return Effect.succeed(rows)
+ return sql`
+ select * from messages where id = ${messageId}
+ `
+ }))
+}
+
+
+=== [R1] Refactor 2: "Wrap with Effect.gen" ===
+
+--- file:///.src/togglePipeStyle_nestedCallback.ts ---
+// refactor: 11:9-11:10
+import * as Effect from "effect/Effect"
+
+type SqlResult = ReadonlyArray<{ id: number }>
+
+const sql = (_strings: TemplateStringsArray, ..._args: ReadonlyArray): Effect.Effect =>
+ Effect.succeed([])
+
+export const insertEnvelope = {
+ pg: () => (_row: { id: string }, messageId: string) =>
+ Effect.gen(function*() { return yield* sql`
+ select * from messages where id = ${messageId}
+ ` }).pipe(Effect.flatMap((rows) => {
+ if (rows.length > 0) return Effect.succeed(rows)
+ return sql`
+ select * from messages where id = ${messageId}
+ `
+ }))
+}
+
+
+=== [R1] Refactor 3: "Toggle return type annotation" ===
+
+--- file:///.src/togglePipeStyle_nestedCallback.ts ---
+// refactor: 11:9-11:10
+import * as Effect from "effect/Effect"
+
+type SqlResult = ReadonlyArray<{ id: number }>
+
+const sql = (_strings: TemplateStringsArray, ..._args: ReadonlyArray): Effect.Effect =>
+ Effect.succeed([])
+
+export const insertEnvelope = {
+ pg: () => (_row: { id: string }, messageId: string): Effect.Effect =>
+ sql`
+ select * from messages where id = ${messageId}
+ `.pipe(Effect.flatMap((rows) => {
+ if (rows.length > 0) return Effect.succeed(rows)
+ return sql`
+ select * from messages where id = ${messageId}
+ `
+ }))
+}
+
diff --git a/testdata/baselines/reference/effect-v4/wrapWithEffectGen.refactors.txt b/testdata/baselines/reference/effect-v4/wrapWithEffectGen.refactors.txt
index 392208f..7ef1c6e 100644
--- a/testdata/baselines/reference/effect-v4/wrapWithEffectGen.refactors.txt
+++ b/testdata/baselines/reference/effect-v4/wrapWithEffectGen.refactors.txt
@@ -160,7 +160,7 @@ export const test1 = Effect.succeed(42)
export const test3 = test1
-export const test2 = pipe(Effect.succeed(42), Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test2 = pipe(Effect.succeed(42), Effect.map((n) => n + 1), Effect.map((n) => n - 1))
export const test4 = pipe(
Effect.succeed(42),
@@ -226,7 +226,7 @@ export const test1 = Effect.succeed(42)
export const test3 = test1
-export const test2 = pipe(Effect.succeed(42), Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test2 = pipe(Effect.succeed(42), Effect.map((n) => n + 1), Effect.map((n) => n - 1))
export const test4 = pipe(
Effect.succeed(42),
@@ -297,7 +297,7 @@ export const test2 = Effect.succeed(42).pipe(
Effect.map((n) => n - 1)
)
-export const test4 = Effect.succeed(42).pipe(Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test4 = Effect.succeed(42).pipe(Effect.map((n) => n + 1), Effect.map((n) => n - 1))
=== [R5] Refactor 2: "Rewrite to datafirst" ===
@@ -381,7 +381,7 @@ export const test2 = Effect.succeed(42).pipe(
Effect.map((n) => n - 1)
)
-export const test4 = Effect.succeed(42).pipe(Effect.map(n => n + 1), Effect.map(n => n - 1))
+export const test4 = Effect.succeed(42).pipe(Effect.map((n) => n + 1), Effect.map((n) => n - 1))
=== [R6] Refactor 2: "Wrap with Effect.gen" ===
diff --git a/testdata/tests/effect-v4-refactors/togglePipeStyle_nestedCallback.ts b/testdata/tests/effect-v4-refactors/togglePipeStyle_nestedCallback.ts
new file mode 100644
index 0000000..99be3e2
--- /dev/null
+++ b/testdata/tests/effect-v4-refactors/togglePipeStyle_nestedCallback.ts
@@ -0,0 +1,19 @@
+// refactor: 11:9-11:10
+import * as Effect from "effect/Effect"
+
+type SqlResult = ReadonlyArray<{ id: number }>
+
+const sql = (_strings: TemplateStringsArray, ..._args: ReadonlyArray): Effect.Effect =>
+ Effect.succeed([])
+
+export const insertEnvelope = {
+ pg: () => (_row: { id: string }, messageId: string) =>
+ sql`
+ select * from messages where id = ${messageId}
+ `.pipe(Effect.flatMap((rows) => {
+ if (rows.length > 0) return Effect.succeed(rows)
+ return sql`
+ select * from messages where id = ${messageId}
+ `
+ }))
+}