Merge pull request 'refactor: rename casRef to x-cas-ref for JSON Schema compliance (Phase 3)' (#292) from feat/285-phase3-x-cas-ref into main
This commit was merged in pull request #292.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
END,
|
||||
START,
|
||||
type ModeratorTable,
|
||||
type WorkflowDefinition,
|
||||
} from "@uncaged/workflow-protocol";
|
||||
import * as z from "zod/v4";
|
||||
import { buildDescriptor } from "../src/bundle/build-descriptor.js";
|
||||
|
||||
const phaseSchema = z.object({
|
||||
hash: z.string().meta({ "x-cas-ref": true }),
|
||||
title: z.string(),
|
||||
});
|
||||
|
||||
type TestMeta = {
|
||||
planner: { phases: Array<{ hash: string; title: string }>; label: string };
|
||||
};
|
||||
|
||||
const testTable: ModeratorTable<TestMeta> = {
|
||||
[START]: [{ condition: "FALLBACK", role: "planner" }],
|
||||
planner: [{ condition: "FALLBACK", role: END }],
|
||||
};
|
||||
|
||||
describe("buildDescriptor", () => {
|
||||
test("preserves x-cas-ref in role JSON Schema", () => {
|
||||
const def: WorkflowDefinition<TestMeta> = {
|
||||
description: "test workflow",
|
||||
roles: {
|
||||
planner: {
|
||||
description: "plans work",
|
||||
systemPrompt: "plan",
|
||||
schema: z.object({
|
||||
phases: z.array(phaseSchema),
|
||||
label: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
table: testTable,
|
||||
};
|
||||
|
||||
const descriptor = buildDescriptor(def);
|
||||
const props = (descriptor.roles.planner.schema as { properties: Record<string, unknown> })
|
||||
.properties;
|
||||
const phaseProps = (
|
||||
(props.phases as { items: { properties: Record<string, unknown> } }).items
|
||||
).properties;
|
||||
|
||||
expect((phaseProps.hash as Record<string, unknown>)["x-cas-ref"]).toBe(true);
|
||||
expect((phaseProps.title as Record<string, unknown>)["x-cas-ref"]).toBeUndefined();
|
||||
expect((props.label as Record<string, unknown>)["x-cas-ref"]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -29,6 +29,9 @@
|
||||
"zod": "^4.0.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "bun test"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as z from "zod/v4";
|
||||
import { collectCasRefs } from "../src/collect-cas-refs.js";
|
||||
|
||||
const phaseSchema = z.object({
|
||||
hash: z.string().meta({ casRef: true }),
|
||||
hash: z.string().meta({ 'x-cas-ref': true }),
|
||||
title: z.string(),
|
||||
});
|
||||
|
||||
@@ -19,9 +19,9 @@ const plannerMetaSchema = z.discriminatedUnion("status", [
|
||||
]);
|
||||
|
||||
describe("collectCasRefs", () => {
|
||||
test("1. flat field with casRef annotation", () => {
|
||||
test("1. flat field with x-cas-ref annotation", () => {
|
||||
const schema = z.object({
|
||||
completedPhase: z.string().meta({ casRef: true }),
|
||||
completedPhase: z.string().meta({ 'x-cas-ref': true }),
|
||||
});
|
||||
expect(collectCasRefs(schema, { completedPhase: "BHAAAAAAAAAAA" })).toEqual(["BHAAAAAAAAAAA"]);
|
||||
});
|
||||
@@ -29,7 +29,7 @@ describe("collectCasRefs", () => {
|
||||
test("2. plain string without annotation is ignored", () => {
|
||||
const schema = z.object({
|
||||
summary: z.string(),
|
||||
completedPhase: z.string().meta({ casRef: true }),
|
||||
completedPhase: z.string().meta({ 'x-cas-ref': true }),
|
||||
});
|
||||
expect(
|
||||
collectCasRefs(schema, {
|
||||
@@ -76,8 +76,8 @@ describe("collectCasRefs", () => {
|
||||
|
||||
test("5. null and undefined annotated fields are skipped", () => {
|
||||
const schema = z.object({
|
||||
ref: z.string().meta({ casRef: true }).nullable(),
|
||||
optionalRef: z.string().meta({ casRef: true }).optional(),
|
||||
ref: z.string().meta({ 'x-cas-ref': true }).nullable(),
|
||||
optionalRef: z.string().meta({ 'x-cas-ref': true }).optional(),
|
||||
});
|
||||
expect(collectCasRefs(schema, { ref: null, optionalRef: undefined })).toEqual([]);
|
||||
expect(collectCasRefs(schema, { ref: "BH55555555555", optionalRef: undefined })).toEqual([
|
||||
@@ -89,7 +89,7 @@ describe("collectCasRefs", () => {
|
||||
const schema = z.object({
|
||||
label: z.string(),
|
||||
phase: z.object({
|
||||
hash: z.string().meta({ casRef: true }),
|
||||
hash: z.string().meta({ 'x-cas-ref': true }),
|
||||
title: z.string(),
|
||||
}),
|
||||
tags: z.array(z.string()),
|
||||
|
||||
@@ -6,7 +6,7 @@ type DefPipeIn = { in: ZodSchema };
|
||||
|
||||
function hasCasRef(schema: ZodSchema): boolean {
|
||||
const meta = z.globalRegistry.get(schema);
|
||||
return meta !== undefined && meta.casRef === true;
|
||||
return meta !== undefined && meta["x-cas-ref"] === true;
|
||||
}
|
||||
|
||||
function walkOptional(schema: z.ZodOptional<ZodSchema>, data: unknown): string[] {
|
||||
@@ -116,7 +116,7 @@ function walkCasRefs(schema: ZodSchema, data: unknown): string[] {
|
||||
}
|
||||
}
|
||||
|
||||
/** Collect CAS content hashes from meta using `casRef` annotations on the Zod schema. */
|
||||
/** Collect CAS content hashes from meta using `x-cas-ref` annotations on the Zod schema. */
|
||||
export function collectCasRefs(schema: ZodSchema, data: unknown): string[] {
|
||||
return walkCasRefs(schema, data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user