mirror of
https://github.com/morluto/rea.git
synced 2026-10-27 01:45:32 +00:00
fix(contracts): honor options outside the schema projection cache
Bypass target-only memoization when Standard JSON Schema library options are supplied. Verify shared and inline projections remain independent in either call order.
This commit is contained in:
1 parent
204b9f3ac1
commit
0df0e4f53e
2 files changed
+38
-3
No files matched your search
@@ -10,9 +10,41 @@ import {
|
||||
presentInputJsonSchema,
|
||||
} from "./inputSchemaPresentation.js";
|
||||
import { toolContract } from "./toolContracts.js";
|
||||
import { toolInputSchemaWithMetadata } from "./toolSchemaMetadata.js";
|
||||
import {
|
||||
toolInputSchemaWithMetadata,
|
||||
transformAdvertisedInputJsonSchema,
|
||||
} from "./toolSchemaMetadata.js";
|
||||
import { JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE } from "./javascript/javascriptRuntimeReconciliationExample.js";
|
||||
|
||||
it.each(["draft-2020-12", "draft-07"] as const)(
|
||||
"honors projection options independently of cached wire transformations in %s",
|
||||
(target) => {
|
||||
const range = z.strictObject({ offset: z.number(), length: z.number() });
|
||||
const canonical = toolInputSchemaWithMetadata({
|
||||
...toolContract("open_binary"),
|
||||
inputSchema: z.strictObject({ before: range, after: range }),
|
||||
});
|
||||
const transform = (schema: Record<string, unknown>) => ({
|
||||
...schema,
|
||||
title: "Transformed range inputs",
|
||||
});
|
||||
const options = { target, libraryOptions: { reused: "inline" as const } };
|
||||
for (const inlineFirst of [false, true]) {
|
||||
const wrapped = transformAdvertisedInputJsonSchema(canonical, transform);
|
||||
const project = wrapped["~standard"].jsonSchema.input;
|
||||
if (inlineFirst) project(options);
|
||||
const shared = project({ target });
|
||||
expect(JSON.stringify(shared)).toContain('"$ref":');
|
||||
const inline = project(options);
|
||||
expect(inline).toEqual(
|
||||
transform(canonical["~standard"].jsonSchema.input(options)),
|
||||
);
|
||||
expect(JSON.stringify(inline)).not.toContain('"$ref":');
|
||||
expect(project({ target })).toBe(shared);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it.each(["draft-2020-12", "draft-07"] as const)(
|
||||
"preserves the complete inline Evidence contract before deferred authentication in %s",
|
||||
(target) => {
|
||||
|
||||
@@ -146,7 +146,10 @@ export const transformAdvertisedInputJsonSchema = <Schema>(
|
||||
const byTarget = new Map<string, Record<string, unknown>>();
|
||||
const transformedInput = (options: unknown): unknown => {
|
||||
const target = Reflect.get(options as object, "target");
|
||||
if (typeof target === "string") {
|
||||
const cacheable =
|
||||
typeof target === "string" &&
|
||||
Reflect.get(options as object, "libraryOptions") === undefined;
|
||||
if (cacheable) {
|
||||
const cached = byTarget.get(target);
|
||||
if (cached !== undefined) return cached;
|
||||
}
|
||||
@@ -154,7 +157,7 @@ export const transformAdvertisedInputJsonSchema = <Schema>(
|
||||
const transformed = isSchemaRecord(projected)
|
||||
? transform(projected)
|
||||
: projected;
|
||||
if (typeof target === "string" && isSchemaRecord(transformed))
|
||||
if (cacheable && isSchemaRecord(transformed))
|
||||
byTarget.set(target, transformed);
|
||||
return transformed;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user