fix(schema): preserve user-defined JSON schema for Python list[dict] parameters (#7496)
* fix(schema): preserve user-defined JSON schema for Python list[dict] Fixes issue where JSON schema properties manually defined in the UI are lost when saving Python scripts with list[dict] or untyped array parameters. Changes: - Preserve all items fields (properties, required, additionalProperties, etc.) - Preserve items.type instead of hardcoding "object" - Preserve type for untyped parameters using nullish coalescing - Add type safety check for items preservation The Python parser cannot infer object properties from list[dict] annotations. This fix preserves user-defined schema fields when parser cannot infer structure. Fixes #7209 * fix(schema): preserve all fields for untyped lists, not just properties Address bot feedback for consistency. The untyped list branch now preserves all user-defined fields (required, additionalProperties, enum, etc.) just like the record[] branch, instead of only preserving properties. This ensures users who define required fields or enum values for untyped list parameters don't lose that data on save. Related to #7209 * nits and publish --------- Co-authored-by: Devdatta Talele <devtalele0@gmail.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
/**
|
||||
* Type alias for enum values - can be an array of strings or undefined
|
||||
*/
|
||||
export type EnumType = string[] | { label: string; value: string }[] | undefined;
|
||||
export type EnumType =
|
||||
| string[]
|
||||
| { label: string; value: string }[]
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* Represents a property in a JSON schema with various validation and display options
|
||||
@@ -40,6 +43,16 @@ export interface SchemaProperty {
|
||||
originalType?: string;
|
||||
}
|
||||
|
||||
const ITEMS_PRESERVED_FIELDS = [
|
||||
"properties",
|
||||
"required",
|
||||
"additionalProperties",
|
||||
"enum",
|
||||
"resourceType",
|
||||
"contentEncoding",
|
||||
"description",
|
||||
] as (keyof SchemaProperty["items"])[];
|
||||
|
||||
/**
|
||||
* Converts argument signature types to JSON schema properties.
|
||||
* This function handles various Windmill-specific types and converts them
|
||||
@@ -54,22 +67,22 @@ export function argSigToJsonSchemaType(
|
||||
| string
|
||||
| { resource: string | null }
|
||||
| {
|
||||
list:
|
||||
| (string | { name?: string; props?: { key: string; typ: any }[] })
|
||||
| { str: any }
|
||||
| { object: { name?: string; props?: { key: string; typ: any }[] } }
|
||||
| null;
|
||||
}
|
||||
list:
|
||||
| (string | { name?: string; props?: { key: string; typ: any }[] })
|
||||
| { str: any }
|
||||
| { object: { name?: string; props?: { key: string; typ: any }[] } }
|
||||
| null;
|
||||
}
|
||||
| { dynselect: string }
|
||||
| { dynmultiselect: string }
|
||||
| { str: string[] | null }
|
||||
| { object: { name?: string; props?: { key: string; typ: any }[] } }
|
||||
| {
|
||||
oneof: {
|
||||
label: string;
|
||||
properties: { key: string; typ: any }[];
|
||||
}[];
|
||||
},
|
||||
oneof: {
|
||||
label: string;
|
||||
properties: { key: string; typ: any }[];
|
||||
}[];
|
||||
},
|
||||
oldS: SchemaProperty
|
||||
): void {
|
||||
const newS: SchemaProperty = { type: "" };
|
||||
@@ -206,15 +219,34 @@ export function argSigToJsonSchemaType(
|
||||
}
|
||||
newS.items = { type: "object", properties: properties };
|
||||
} else {
|
||||
newS.items = { type: "object" };
|
||||
// Preserve ALL user-defined fields when parser cannot infer structure
|
||||
newS.items = { type: oldS.items?.type || "object" };
|
||||
|
||||
if (oldS.items && typeof oldS.items === "object") {
|
||||
ITEMS_PRESERVED_FIELDS.forEach((field) => {
|
||||
if (oldS.items && oldS.items[field] !== undefined) {
|
||||
newS.items![field] = oldS.items[field];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
newS.originalType = "record[]";
|
||||
} else {
|
||||
newS.items = { type: "object" };
|
||||
// Preserve ALL user-defined fields for untyped lists (same as record[] branch)
|
||||
newS.items = { type: oldS.items?.type || "object" };
|
||||
|
||||
if (oldS.items && typeof oldS.items === "object") {
|
||||
ITEMS_PRESERVED_FIELDS.forEach((field) => {
|
||||
if (oldS.items && oldS.items[field] !== undefined) {
|
||||
newS.items![field] = oldS.items[field];
|
||||
}
|
||||
});
|
||||
}
|
||||
newS.originalType = "object[]";
|
||||
}
|
||||
} else {
|
||||
newS.type = "object";
|
||||
// Preserve existing type when inference fails, default to "object" for undefined/null
|
||||
newS.type = oldS.type ?? "object";
|
||||
}
|
||||
|
||||
const preservedFields = [
|
||||
|
||||
Reference in New Issue
Block a user