import { assert } from "@std/assert"; import { transformSource } from "./utils.ts"; const COMMON_TOOLS_D_TS = ` export declare const CELL_BRAND: unique symbol; export interface Cell { [CELL_BRAND]: "cell"; } export interface CellTypeConstructor { of(value: U): any; for(cause: unknown): any; } export declare const Cell: CellTypeConstructor; export declare const OpaqueCell: CellTypeConstructor; export declare const Stream: CellTypeConstructor; export declare function wish(query: string): T; export declare function generateObject(opts: any): T; `; const options = { types: { "commontools.d.ts": COMMON_TOOLS_D_TS }, }; Deno.test("Schema Injection - Cell.of", async () => { const code = ` /// import { Cell } from "commontools"; const c1 = Cell.of("hello"); const c2 = Cell.of(123); `.trim(); const result = await transformSource(code, options); const normalize = (s: string) => s.replace(/\s+/g, " "); assert( normalize(result).includes( 'Cell.of("hello", { type: "string" } as const satisfies __ctHelpers.JSONSchema)', ), ); assert( normalize(result).includes( 'Cell.of(123, { type: "number" } as const satisfies __ctHelpers.JSONSchema)', ), ); }); Deno.test("Schema Injection - Cell.for", async () => { const code = ` /// import { Cell } from "commontools"; const c1 = Cell.for("cause"); const c2: Cell = Cell.for("cause"); `.trim(); const result = await transformSource(code, options); const normalize = (s: string) => s.replace(/\s+/g, " "); assert( normalize(result).includes( 'Cell.for("cause").asSchema({ type: "string" } as const satisfies __ctHelpers.JSONSchema)', ), ); assert( normalize(result).includes( 'Cell.for("cause").asSchema({ type: "number" } as const satisfies __ctHelpers.JSONSchema)', ), ); }); Deno.test("Schema Injection - wish", async () => { const code = ` /// import { wish } from "commontools"; const w1 = wish("query"); const w2: string = wish("query"); `.trim(); const result = await transformSource(code, options); const normalize = (s: string) => s.replace(/\s+/g, " "); assert( normalize(result).includes( 'wish("query", { type: "string" } as const satisfies __ctHelpers.JSONSchema)', ), ); assert( normalize(result).includes( 'wish("query", { type: "string" } as const satisfies __ctHelpers.JSONSchema)', ), ); }); Deno.test("Schema Injection - generateObject", async () => { const code = ` /// import { generateObject } from "commontools"; const g1 = generateObject({ model: "gpt-4" }); const g2: { object: number } = generateObject({ model: "gpt-4" }); const g3 = generateObject({ model: "gpt-4", schema: { type: "string" } }); `.trim(); const result = await transformSource(code, options); const normalize = (s: string) => s.replace(/\s+/g, " "); assert( normalize(result).includes( 'generateObject({ model: "gpt-4", schema: { type: "string" } as const satisfies __ctHelpers.JSONSchema })', ), ); assert( normalize(result).includes( 'generateObject({ model: "gpt-4", schema: { type: "number" } as const satisfies __ctHelpers.JSONSchema })', ), ); // Should not double inject assert( normalize(result).includes( 'generateObject({ model: "gpt-4", schema: { type: "string" } })', ), ); assert( !normalize(result).includes( 'schema: { type: "string" }, schema: { type: "string" }', ), ); }); Deno.test("Schema Injection - Cell-like classes", async () => { const code = ` /// import { OpaqueCell, Stream } from "commontools"; const o1 = OpaqueCell.of(true); const s1 = Stream.of(1); `.trim(); const result = await transformSource(code, options); const normalize = (s: string) => s.replace(/\s+/g, " "); assert( normalize(result).includes( 'OpaqueCell.of(true, { type: "boolean" } as const satisfies __ctHelpers.JSONSchema)', ), ); assert( normalize(result).includes( 'Stream.of(1, { type: "number" } as const satisfies __ctHelpers.JSONSchema)', ), ); });