refactor: consolidate authoring binding copies
This commit is contained in:
@@ -134,7 +134,6 @@ def _analyze(workflow: Workflow) -> _ContextAnalysis:
|
||||
fields_by_node[node_id] = _available_fields(
|
||||
workflow,
|
||||
foreach_nodes,
|
||||
node_id,
|
||||
scopes,
|
||||
scopes_by_node,
|
||||
)
|
||||
@@ -144,11 +143,9 @@ def _analyze(workflow: Workflow) -> _ContextAnalysis:
|
||||
def _available_fields(
|
||||
workflow: Workflow,
|
||||
foreach_nodes: Mapping[str, ForeachNode],
|
||||
node_id: str,
|
||||
scopes: set[FrameScope],
|
||||
scopes_by_node: Mapping[str, set[FrameScope]],
|
||||
) -> tuple[ContextFieldAvailability, ...]:
|
||||
del node_id
|
||||
fields_by_name: dict[str, ContextFieldContract] = {}
|
||||
scopes_by_field: dict[str, set[FrameScope]] = {}
|
||||
for scope in sorted(scopes, key=lambda value: value or ""):
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useConsoleWorkspace } from "../context.js";
|
||||
import {
|
||||
createDraftAuthoringClient,
|
||||
copyInputBinding,
|
||||
copyStepInputBinding,
|
||||
type DraftAuthoringClient,
|
||||
} from "../domain/draft-authoring-client.js";
|
||||
@@ -193,26 +194,7 @@ const copyOutputBindings = (
|
||||
|
||||
const copyWorkflowOutputBindings = (
|
||||
bindings: ReadonlyArray<InputBinding>,
|
||||
): ReadonlyArray<InputBinding> => bindings.map((binding) => (
|
||||
"path" in binding
|
||||
? {
|
||||
path:
|
||||
typeof binding.path === "string"
|
||||
? binding.path
|
||||
: { root: binding.path.root, parts: [...binding.path.parts] },
|
||||
target:
|
||||
typeof binding.target === "string"
|
||||
? binding.target
|
||||
: { root: binding.target.root, parts: [...binding.target.parts] },
|
||||
}
|
||||
: {
|
||||
value: copyJson(binding.value),
|
||||
target:
|
||||
typeof binding.target === "string"
|
||||
? binding.target
|
||||
: { root: binding.target.root, parts: [...binding.target.parts] },
|
||||
}
|
||||
));
|
||||
): ReadonlyArray<InputBinding> => bindings.map(copyInputBinding);
|
||||
|
||||
const copyContractPatch = (patch: WorkflowContractPatch): WorkflowContractPatch => ({
|
||||
...(patch.inputSchema !== undefined
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
type SetWorkflowStartInput,
|
||||
type UpdateCapabilityStepInput,
|
||||
} from "./draft-workspace-models.js";
|
||||
import { createDraftAuthoringClient } from "./draft-authoring-client.js";
|
||||
import { copyInputBinding, createDraftAuthoringClient } from "./draft-authoring-client.js";
|
||||
import type { ConsoleWriteExecutor } from "./write-executor.js";
|
||||
|
||||
const canonicalWorkspace = {
|
||||
@@ -65,6 +65,19 @@ const createExecutor = () => {
|
||||
};
|
||||
|
||||
describe("DraftAuthoringClient", () => {
|
||||
it("copies workflow-compatible input bindings without sharing nested paths", () => {
|
||||
const binding = {
|
||||
path: { root: "state" as const, parts: ["report"] },
|
||||
target: { root: "local" as const, parts: ["text"] },
|
||||
} satisfies InputBinding;
|
||||
|
||||
const copied = copyInputBinding(binding);
|
||||
expect(copied).not.toBe(binding);
|
||||
if (!("path" in copied)) throw new Error("expected a path binding");
|
||||
expect(copied.path).not.toBe(binding.path);
|
||||
expect(copied.target).not.toBe(binding.target);
|
||||
});
|
||||
|
||||
it("lowers all six authoring operations and decodes canonical workspaces", async () => {
|
||||
const { executor: writeExecutor, run } = createExecutor();
|
||||
const client = createDraftAuthoringClient(writeExecutor);
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
type CreateEmptyDraftInput,
|
||||
type CreateFromCapabilityInput,
|
||||
type DraftWorkspace,
|
||||
type InputBinding,
|
||||
type JsonValue,
|
||||
type InputExpression,
|
||||
type InputPath,
|
||||
@@ -112,27 +113,31 @@ export const copyInputExpression = (
|
||||
}
|
||||
};
|
||||
|
||||
export const copyStepInputBinding = (
|
||||
binding: StepInputBinding,
|
||||
): StepInputBinding => {
|
||||
export const copyInputBinding = (binding: InputBinding): InputBinding => {
|
||||
if ("path" in binding) {
|
||||
return {
|
||||
path: copyInputPath(binding.path),
|
||||
target: copyLocalInputPath(binding.target),
|
||||
};
|
||||
}
|
||||
if ("value" in binding) {
|
||||
return {
|
||||
target: copyLocalInputPath(binding.target),
|
||||
value: copyJsonValue(binding.value),
|
||||
};
|
||||
}
|
||||
return {
|
||||
target: copyLocalInputPath(binding.target),
|
||||
expression: copyInputExpression(binding.expression),
|
||||
value: copyJsonValue(binding.value),
|
||||
};
|
||||
};
|
||||
|
||||
export const copyStepInputBinding = (
|
||||
binding: StepInputBinding,
|
||||
): StepInputBinding => {
|
||||
if ("expression" in binding) {
|
||||
return {
|
||||
target: copyLocalInputPath(binding.target),
|
||||
expression: copyInputExpression(binding.expression),
|
||||
};
|
||||
}
|
||||
return copyInputBinding(binding);
|
||||
};
|
||||
|
||||
const copyOutputBinding = (binding: OutputBinding): OutputBinding => ({
|
||||
source:
|
||||
typeof binding.source === "string"
|
||||
|
||||
Reference in New Issue
Block a user