fix(editor): restore build after toGraph signature change + client/backend numeric parity
This commit is contained in:
@@ -123,4 +123,44 @@ describe("toGraph — schema-typed coercion on save", () => {
|
||||
);
|
||||
expect(g.nodes[0].config.status).toBe(200);
|
||||
});
|
||||
|
||||
it("hex literals on integer fields are not coerced (backend rejects them too)", () => {
|
||||
const g = toGraph(
|
||||
[{
|
||||
id: "n1", type: "vc",
|
||||
position: { x: 0, y: 0 },
|
||||
data: { typeId: "test.numberfield", config: { status: "0x1F" } },
|
||||
}],
|
||||
[],
|
||||
[numberNodeType],
|
||||
);
|
||||
// Kept as string so backend surfaces the parse error at run time.
|
||||
expect(g.nodes[0].config.status).toBe("0x1F");
|
||||
});
|
||||
|
||||
it("scientific-notation strings on integer fields are not coerced (backend rejects them)", () => {
|
||||
const g = toGraph(
|
||||
[{
|
||||
id: "n1", type: "vc",
|
||||
position: { x: 0, y: 0 },
|
||||
data: { typeId: "test.numberfield", config: { status: "1e2" } },
|
||||
}],
|
||||
[],
|
||||
[numberNodeType],
|
||||
);
|
||||
expect(g.nodes[0].config.status).toBe("1e2");
|
||||
});
|
||||
|
||||
it("scientific-notation strings on number fields ARE coerced (backend accepts them)", () => {
|
||||
const g = toGraph(
|
||||
[{
|
||||
id: "n1", type: "vc",
|
||||
position: { x: 0, y: 0 },
|
||||
data: { typeId: "test.numberfield", config: { ratio: "1e2" } },
|
||||
}],
|
||||
[],
|
||||
[numberNodeType],
|
||||
);
|
||||
expect(g.nodes[0].config.ratio).toBe(100);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,11 +79,21 @@ export function coerceConfigForSave(
|
||||
}
|
||||
switch (prop.type) {
|
||||
case "integer": {
|
||||
// Match backend long.TryParse(NumberStyles.Integer): sign + digits,
|
||||
// optional leading/trailing whitespace. No hex, no scientific.
|
||||
if (!/^\s*-?\d+\s*$/.test(value)) { out[name] = value; break; }
|
||||
const n = Number(value);
|
||||
out[name] = Number.isInteger(n) ? n : value;
|
||||
out[name] = Number.isSafeInteger(n) ? n : value;
|
||||
break;
|
||||
}
|
||||
case "number": {
|
||||
// Match backend double.TryParse(NumberStyles.Float): sign + digits +
|
||||
// optional fractional + optional exponent, optional whitespace.
|
||||
// Rejects hex (`0x…`). Backend Float style accepts scientific
|
||||
// notation, so we do too here.
|
||||
if (!/^\s*-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?\s*$/.test(value)) {
|
||||
out[name] = value; break;
|
||||
}
|
||||
const n = Number(value);
|
||||
out[name] = Number.isFinite(n) ? n : value;
|
||||
break;
|
||||
|
||||
@@ -70,7 +70,7 @@ export default function EditorPage() {
|
||||
() =>
|
||||
apiFetch<void>(`/api/workflows/${id}`, {
|
||||
method: "PUT",
|
||||
body: { name: wf.data!.name, graph: toGraph(nodes, edges) },
|
||||
body: { name: wf.data!.name, graph: toGraph(nodes, edges, nts.data ?? []) },
|
||||
}),
|
||||
{ onSuccess: () => id && invalidate(qk.workflow(id)) },
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user