fix(httpapi): model optional worktree payload as no content (#29246)
This commit is contained in:
@@ -5,7 +5,7 @@ import { Session } from "@/session/session"
|
|||||||
import { Worktree } from "@/worktree"
|
import { Worktree } from "@/worktree"
|
||||||
import { NonNegativeInt } from "@opencode-ai/core/schema"
|
import { NonNegativeInt } from "@opencode-ai/core/schema"
|
||||||
import { Schema } from "effect"
|
import { Schema } from "effect"
|
||||||
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
|
||||||
import { Authorization } from "../middleware/authorization"
|
import { Authorization } from "../middleware/authorization"
|
||||||
import { InstanceContextMiddleware } from "../middleware/instance-context"
|
import { InstanceContextMiddleware } from "../middleware/instance-context"
|
||||||
import {
|
import {
|
||||||
@@ -168,7 +168,7 @@ export const ExperimentalApi = HttpApi.make("experimental")
|
|||||||
HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
|
HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
|
||||||
disableCodecs: true,
|
disableCodecs: true,
|
||||||
query: WorkspaceRoutingQuery,
|
query: WorkspaceRoutingQuery,
|
||||||
payload: Schema.UndefinedOr(Worktree.CreateInput),
|
payload: [HttpApiSchema.NoContent, Worktree.CreateInput],
|
||||||
success: described(Worktree.Info, "Worktree created"),
|
success: described(Worktree.Info, "Worktree created"),
|
||||||
error: WorktreeApiError,
|
error: WorktreeApiError,
|
||||||
}).annotateMerge(
|
}).annotateMerge(
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper
|
|||||||
})
|
})
|
||||||
|
|
||||||
const worktreeCreate = Effect.fn("ExperimentalHttpApi.worktreeCreate")(function* (ctx: {
|
const worktreeCreate = Effect.fn("ExperimentalHttpApi.worktreeCreate")(function* (ctx: {
|
||||||
payload: Worktree.CreateInput | undefined
|
payload: typeof Worktree.CreateInput.Type | void
|
||||||
}) {
|
}) {
|
||||||
return yield* mapWorktreeError(worktreeSvc.create(ctx.payload))
|
return yield* mapWorktreeError(worktreeSvc.create(ctx.payload ?? undefined))
|
||||||
})
|
})
|
||||||
|
|
||||||
const worktreeRemove = Effect.fn("ExperimentalHttpApi.worktreeRemove")(function* (input: {
|
const worktreeRemove = Effect.fn("ExperimentalHttpApi.worktreeRemove")(function* (input: {
|
||||||
|
|||||||
@@ -228,6 +228,28 @@ describe("worktree endpoint reproduction", () => {
|
|||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
worktreeTest(
|
||||||
|
"direct HttpApi worktree create rejects explicit null payload",
|
||||||
|
() =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const test = yield* TestInstance
|
||||||
|
const server = yield* serverScoped()
|
||||||
|
|
||||||
|
const response = yield* request(
|
||||||
|
server,
|
||||||
|
`${ExperimentalPaths.worktree}?directory=${encodeURIComponent(test.directory)}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: "null",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toBe(400)
|
||||||
|
}),
|
||||||
|
{ git: true },
|
||||||
|
)
|
||||||
|
|
||||||
worktreeTest(
|
worktreeTest(
|
||||||
"workspace worktree create does not hang",
|
"workspace worktree create does not hang",
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
Reference in New Issue
Block a user