diff --git a/integration-test/langfuse-integration-node.spec.ts b/integration-test/langfuse-integration-node.spec.ts index 20333ab9..121a0505 100644 --- a/integration-test/langfuse-integration-node.spec.ts +++ b/integration-test/langfuse-integration-node.spec.ts @@ -114,36 +114,39 @@ describe("Langfuse Node.js", () => { }); }); - it("create span", async () => { - const trace = langfuse.trace({ name: "trace-name-span" }); - const span = trace.span({ - name: "span-name", - startTime: new Date("2020-01-01T00:00:00.000Z"), - }); - await langfuse.flushAsync(); - // check from get api if trace is created - const res = await axios.get(`${LANGFUSE_BASEURL}/api/public/observations/${span.id}`, { headers: getHeaders() }); - expect(res.data).toMatchObject({ - id: span.id, - name: "span-name", - type: "SPAN", - startTime: new Date("2020-01-01T00:00:00.000Z").toISOString(), - completionStartTime: null, - endTime: null, - metadata: null, - model: null, - modelParameters: null, - input: null, - output: null, - level: "DEFAULT", - parentObservationId: null, - completionTokens: 0, - promptTokens: 0, - totalTokens: 0, - statusMessage: null, - traceId: trace.id, - version: null, - }); + it.only("create span", async () => { + const a = await langfuse.fetchTraces({ tags: ["tag1", "tag2"] }); + console.log(a); + + // const trace = langfuse.trace({ name: "trace-name-span" }); + // const span = trace.span({ + // name: "span-name", + // startTime: new Date("2020-01-01T00:00:00.000Z"), + // }); + // await langfuse.flushAsync(); + // // check from get api if trace is created + // const res = await axios.get(`${LANGFUSE_BASEURL}/api/public/observations/${span.id}`, { headers: getHeaders() }); + // expect(res.data).toMatchObject({ + // id: span.id, + // name: "span-name", + // type: "SPAN", + // startTime: new Date("2020-01-01T00:00:00.000Z").toISOString(), + // completionStartTime: null, + // endTime: null, + // metadata: null, + // model: null, + // modelParameters: null, + // input: null, + // output: null, + // level: "DEFAULT", + // parentObservationId: null, + // completionTokens: 0, + // promptTokens: 0, + // totalTokens: 0, + // statusMessage: null, + // traceId: trace.id, + // version: null, + // }); }); it("update a span", async () => { diff --git a/langfuse-core/src/utils.ts b/langfuse-core/src/utils.ts index 46170208..812d59d7 100644 --- a/langfuse-core/src/utils.ts +++ b/langfuse-core/src/utils.ts @@ -114,16 +114,17 @@ export function configLangfuseSDK(params?: LangfuseCoreOptions, secretRequired: } export const encodeQueryParams = (params?: { [key: string]: any }): string => { - const queryParams = new URLSearchParams(); - Object.entries(params ?? {}).forEach(([key, value]) => { - if (value !== undefined && value !== null) { - // check for date - if (value instanceof Date) { - queryParams.append(key, value.toISOString()); - } else { - queryParams.append(key, value.toString()); + const queryParams = Object.entries(params ?? {}) + .map(([key, value]) => { + if (value !== undefined && value !== null) { + const encodedKey = encodeURIComponent(key); + const encodedValue = + value instanceof Date ? encodeURIComponent(value.toISOString()) : encodeURIComponent(value.toString()); + return `${encodedKey}=${encodedValue}`; } - } - }); - return queryParams.toString(); + return null; + }) + .filter((param) => param !== null) + .join("&"); + return queryParams; }; diff --git a/langfuse-core/test/utils.spec.ts b/langfuse-core/test/utils.spec.ts index d5c64a47..342cf8b2 100644 --- a/langfuse-core/test/utils.spec.ts +++ b/langfuse-core/test/utils.spec.ts @@ -5,6 +5,7 @@ import { currentISOTime, currentTimestamp, configLangfuseSDK, + encodeQueryParams, } from "../src/utils"; describe("utils", () => { @@ -42,6 +43,38 @@ describe("utils", () => { expect(currentTimestamp()).toEqual(Date.now()); }); }); + describe("encodeQueryParams", () => { + it("should encode query parameters correctly", () => { + const params = { + name: "John Doe", + age: 30, + active: true, + date: new Date("2022-01-01T00:00:00.000Z"), + empty: null, + undefinedValue: undefined, + }; + const expected = "name=John%20Doe&age=30&active=true&date=2022-01-01T00%3A00%3A00.000Z"; + expect(encodeQueryParams(params)).toEqual(expected); + }); + + it("should encode query params with arrays correctly", () => { + const params = { + tags: ["tag-one", "tag-two"], + }; + const expected = "tags=tag-one%2Ctag-two"; + expect(encodeQueryParams(params)).toEqual(expected); + }); + + it("should handle special characters in keys and values", () => { + const params = { + "key with spaces": "value/with/slash", + "key&with&special": "value?with=query", + }; + const expected = "key%20with%20spaces=value%2Fwith%2Fslash&key%26with%26special=value%3Fwith%3Dquery"; + expect(encodeQueryParams(params)).toEqual(expected); + }); + }); + describe("currentISOTime", () => { it("should get the iso time", () => { jest.setSystemTime(new Date("2022-01-01"));