@cratis/scene.engine 4.16.0 → 4.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,5 +86,11 @@ export function iconProblemsOfProperty(catalog: EffectiveIconCatalog, descriptor
86
86
  return iconProblemsOfItems(catalog, descriptor.item, items, severity, { ...context, path: descriptor.path });
87
87
  }
88
88
 
89
+ if (descriptor.valueType === PropertyValueType.Object && descriptor.properties !== undefined && value !== null && typeof value === 'object' && !Array.isArray(value)) {
90
+ const record = value as Record<string, unknown>;
91
+ return descriptor.properties.flatMap((field) =>
92
+ iconProblemsOfProperty(catalog, { ...field, path: `${descriptor.path}.${field.path}` }, record[field.path], severity, context));
93
+ }
94
+
89
95
  return [];
90
96
  }
@@ -72,6 +72,9 @@ export function validateValue(descriptor: PropertyDescriptor, value: unknown): s
72
72
  case PropertyValueType.Collection:
73
73
  return validateCollection(descriptor, value);
74
74
 
75
+ case PropertyValueType.Object:
76
+ return validateObject(descriptor, value);
77
+
75
78
  case PropertyValueType.Json:
76
79
  return isJsonValue(value) ? undefined : 'expected a JSON value';
77
80
 
@@ -119,6 +122,14 @@ function isJsonValue(value: unknown, parents = new Set<object>()): boolean {
119
122
  return valid;
120
123
  }
121
124
 
125
+ function validateObject(descriptor: PropertyDescriptor, value: unknown): string | undefined {
126
+ if (descriptor.properties === undefined) return isRecord(value) || Array.isArray(value) ? undefined : 'expected a structured value';
127
+ if (!isRecord(value)) return 'expected a structured value';
128
+
129
+ const problem = validateFields(descriptor.properties, value, 'this object').at(0);
130
+ return problem ? `${problem.field} ${problem.problem}` : undefined;
131
+ }
132
+
122
133
  function validateCollection(descriptor: PropertyDescriptor, value: unknown): string | undefined {
123
134
  if (!Array.isArray(value)) return 'expected a list';
124
135
  const constraints = descriptor.constraints ?? {};
@@ -155,13 +166,16 @@ export interface ItemFieldProblem {
155
166
  * @returns Every field that is unknown or has an unacceptable value.
156
167
  */
157
168
  export function validateItemValues(itemDescriptor: CollectionItemDescriptor | undefined, values: Record<string, unknown>): ItemFieldProblem[] {
158
- const fields = itemDescriptor?.properties ?? [];
169
+ return validateFields(itemDescriptor?.properties ?? [], values, 'this collection\'s items');
170
+ }
171
+
172
+ function validateFields(fields: PropertyDescriptor[], values: Record<string, unknown>, owner: string): ItemFieldProblem[] {
159
173
  const problems: ItemFieldProblem[] = [];
160
174
 
161
175
  for (const [field, fieldValue] of Object.entries(values)) {
162
176
  const fieldDescriptor = fields.find(candidate => candidate.path === field);
163
177
  if (!fieldDescriptor) {
164
- problems.push({ field, problem: 'is not a field of this collection\'s items' });
178
+ problems.push({ field, problem: `is not a field of ${owner}` });
165
179
  continue;
166
180
  }
167
181
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.engine",
3
- "version": "4.16.0",
3
+ "version": "4.18.0",
4
4
  "description": "The Scene runtime: walks a Scene element tree and drives whichever renderer is plugged in. Does not know React, or any other rendering platform, exists.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -48,9 +48,9 @@
48
48
  "up": "yarn g:up"
49
49
  },
50
50
  "dependencies": {
51
- "@cratis/scene.model": "4.16.0"
51
+ "@cratis/scene.model": "4.18.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@cratis/scene.model": "4.16.0"
54
+ "@cratis/scene.model": "4.18.0"
55
55
  }
56
56
  }