diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index be300d47dd..66b602bd4b 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -2,7 +2,7 @@ export * as SessionV2 from "./session" export * from "./session/schema" import { Cause, DateTime, Effect, Layer, Schema, Context, Stream } from "effect" -import { and, asc, desc, eq, gt, like, lt, or, type SQL } from "drizzle-orm" +import { and, asc, desc, eq, gt, gte, like, lt, or, type SQL } from "drizzle-orm" import { ProjectV2 } from "./project" import { WorkspaceV2 } from "./workspace" import { ModelV2 } from "./model" @@ -264,7 +264,12 @@ export const layer = Layer.effect( if (input.workspaceID) conditions.push(eq(SessionTable.workspace_id, input.workspaceID)) if ("project" in input) conditions.push(eq(SessionTable.project_id, input.project)) if ("subpath" in input && input.subpath) - conditions.push(or(eq(SessionTable.path, input.subpath), like(SessionTable.path, `${input.subpath}/%`))!) + conditions.push( + or( + eq(SessionTable.path, input.subpath), + and(gte(SessionTable.path, `${input.subpath}/`), lt(SessionTable.path, `${input.subpath}0`)), + )!, + ) if (input.search) conditions.push(like(SessionTable.title, `%${input.search}%`)) if (input.anchor) { conditions.push( diff --git a/packages/core/test/session-create.test.ts b/packages/core/test/session-create.test.ts index 3611935c69..3020ae1e83 100644 --- a/packages/core/test/session-create.test.ts +++ b/packages/core/test/session-create.test.ts @@ -450,4 +450,30 @@ describe("SessionV2.list", () => { expect(new Set(listed.map((item) => item.id))).toEqual(new Set([core.id, nested.id])) }), ) + + it.effect("treats wildcard characters in subpaths literally", () => + Effect.gen(function* () { + const session = yield* SessionV2.Service + const { db } = yield* Database.Service + const exact = yield* session.create({ location }) + const nested = yield* session.create({ location }) + const sibling = yield* session.create({ location }) + + yield* Effect.all([ + db.update(SessionTable).set({ path: "packages/core_test" }).where(eq(SessionTable.id, exact.id)).run(), + db.update(SessionTable).set({ path: "packages/core_test/unit" }).where(eq(SessionTable.id, nested.id)).run(), + db.update(SessionTable).set({ path: "packages/coreXtest/unit" }).where(eq(SessionTable.id, sibling.id)).run(), + ]).pipe(Effect.orDie) + + const listed = yield* session.list({ + project: ProjectV2.ID.global, + subpath: RelativePath.make("packages/core_test"), + }) + + const ids = listed.map((item) => item.id) + expect(ids).toContain(exact.id) + expect(ids).toContain(nested.id) + expect(ids).not.toContain(sibling.id) + }), + ) })