( key: string, label: string, value: T, schemaProperties: ElementSchema["properties"] | undefined, )
| 40 | * @throws AsyncValidationError if schema returns a Promise (not supported) |
| 41 | */ |
| 42 | export function parsePropertyValue<T>( |
| 43 | key: string, |
| 44 | label: string, |
| 45 | value: T, |
| 46 | schemaProperties: ElementSchema["properties"] | undefined, |
| 47 | ): T { |
| 48 | if (!schemaProperties) { |
| 49 | return value; |
| 50 | } |
| 51 | |
| 52 | // If key is not in schema, allow it without validation |
| 53 | // (only validate properties that have explicit schema definitions) |
| 54 | if (!(key in schemaProperties)) { |
| 55 | return value; |
| 56 | } |
| 57 | |
| 58 | // Validate and transform value using the property's type schema |
| 59 | const propertySchema = schemaProperties[key]; |
| 60 | if (propertySchema?.type?.["~standard"]?.validate) { |
| 61 | const result = propertySchema.type["~standard"].validate(value); |
| 62 | |
| 63 | // Check for async result (not supported) |
| 64 | if (result instanceof Promise) { |
| 65 | throw new AsyncValidationError(key, label); |
| 66 | } |
| 67 | |
| 68 | // Check for validation errors (empty issues array is treated as success) |
| 69 | if ("issues" in result && result.issues && result.issues.length > 0) { |
| 70 | const issues = result.issues.map((issue) => issue.message); |
| 71 | throw new PropertyTypeError(key, label, value, issues); |
| 72 | } |
| 73 | |
| 74 | // Return the transformed/validated value |
| 75 | if ("value" in result) { |
| 76 | return result.value as T; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | return value; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Parse all properties of an element through their Standard Schema validators. |
no test coverage detected