@safe-ugc-ui/validator 0.6.0 → 1.0.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.
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ import { UGCCard } from '@safe-ugc-ui/types';
14
14
  /**
15
15
  * Machine-readable error codes for every validation failure type.
16
16
  */
17
- type ValidationErrorCode = 'INVALID_JSON' | 'MISSING_FIELD' | 'INVALID_TYPE' | 'INVALID_VALUE' | 'UNKNOWN_NODE_TYPE' | 'SCHEMA_ERROR' | 'REF_NOT_ALLOWED' | 'DYNAMIC_NOT_ALLOWED' | 'FORBIDDEN_STYLE_PROPERTY' | 'STYLE_VALUE_OUT_OF_RANGE' | 'FORBIDDEN_CSS_FUNCTION' | 'INVALID_COLOR' | 'INVALID_LENGTH' | 'FORBIDDEN_OVERFLOW_VALUE' | 'TRANSFORM_SKEW_FORBIDDEN' | 'EXTERNAL_URL' | 'POSITION_FIXED_FORBIDDEN' | 'POSITION_STICKY_FORBIDDEN' | 'POSITION_ABSOLUTE_NOT_IN_STACK' | 'ASSET_PATH_TRAVERSAL' | 'INVALID_ASSET_PATH' | 'PROTOTYPE_POLLUTION' | 'CARD_SIZE_EXCEEDED' | 'TEXT_CONTENT_SIZE_EXCEEDED' | 'STYLE_SIZE_EXCEEDED' | 'NODE_COUNT_EXCEEDED' | 'LOOP_ITERATIONS_EXCEEDED' | 'NESTED_LOOPS_EXCEEDED' | 'OVERFLOW_AUTO_COUNT_EXCEEDED' | 'OVERFLOW_AUTO_NESTED' | 'STACK_NESTING_EXCEEDED' | 'LOOP_SOURCE_NOT_ARRAY' | 'LOOP_SOURCE_MISSING' | 'STYLE_CIRCULAR_REF' | 'STYLE_REF_NOT_FOUND' | 'INVALID_STYLE_REF' | 'INVALID_STYLE_NAME' | 'INVALID_HOVER_STYLE' | 'HOVER_STYLE_NESTED' | 'TRANSITION_RAW_STRING' | 'TRANSITION_COUNT_EXCEEDED' | 'TRANSITION_PROPERTY_FORBIDDEN';
17
+ type ValidationErrorCode = 'INVALID_JSON' | 'MISSING_FIELD' | 'INVALID_TYPE' | 'INVALID_VALUE' | 'UNKNOWN_NODE_TYPE' | 'SCHEMA_ERROR' | 'REF_NOT_ALLOWED' | 'DYNAMIC_NOT_ALLOWED' | 'FORBIDDEN_STYLE_PROPERTY' | 'STYLE_VALUE_OUT_OF_RANGE' | 'FORBIDDEN_CSS_FUNCTION' | 'INVALID_COLOR' | 'INVALID_LENGTH' | 'FORBIDDEN_OVERFLOW_VALUE' | 'TRANSFORM_SKEW_FORBIDDEN' | 'EXTERNAL_URL' | 'POSITION_FIXED_FORBIDDEN' | 'POSITION_STICKY_FORBIDDEN' | 'POSITION_ABSOLUTE_NOT_IN_STACK' | 'ASSET_PATH_TRAVERSAL' | 'INVALID_ASSET_PATH' | 'PROTOTYPE_POLLUTION' | 'CARD_SIZE_EXCEEDED' | 'TEXT_CONTENT_SIZE_EXCEEDED' | 'STYLE_SIZE_EXCEEDED' | 'NODE_COUNT_EXCEEDED' | 'LOOP_ITERATIONS_EXCEEDED' | 'NESTED_LOOPS_EXCEEDED' | 'OVERFLOW_AUTO_COUNT_EXCEEDED' | 'OVERFLOW_AUTO_NESTED' | 'STACK_NESTING_EXCEEDED' | 'LOOP_SOURCE_NOT_ARRAY' | 'LOOP_SOURCE_MISSING' | 'STYLE_CIRCULAR_REF' | 'STYLE_REF_NOT_FOUND' | 'INVALID_STYLE_REF' | 'INVALID_STYLE_NAME' | 'FRAGMENT_REF_NOT_FOUND' | 'FRAGMENT_NESTED_USE' | 'INVALID_FRAGMENT_NAME' | 'INVALID_HOVER_STYLE' | 'HOVER_STYLE_NESTED' | 'TRANSITION_RAW_STRING' | 'TRANSITION_COUNT_EXCEEDED' | 'TRANSITION_PROPERTY_FORBIDDEN' | 'CONDITION_DEPTH_EXCEEDED';
18
18
  /**
19
19
  * A single validation error with location and diagnostic info.
20
20
  */
@@ -99,15 +99,21 @@ interface TraversalContext {
99
99
  */
100
100
  interface TraversableNode {
101
101
  type: string;
102
- children?: TraversableNode[] | ForLoopLike;
102
+ children?: TraversableRenderable[] | ForLoopLike;
103
103
  style?: Record<string, unknown>;
104
104
  responsive?: Record<string, unknown>;
105
105
  [key: string]: unknown;
106
106
  }
107
+ interface FragmentUseLike {
108
+ $use: string;
109
+ $if?: unknown;
110
+ [key: string]: unknown;
111
+ }
112
+ type TraversableRenderable = TraversableNode | FragmentUseLike;
107
113
  interface ForLoopLike {
108
114
  for: string;
109
115
  in: string;
110
- template: TraversableNode;
116
+ template: TraversableRenderable;
111
117
  }
112
118
  /**
113
119
  * A visitor function called for every node in the tree.
@@ -118,14 +124,14 @@ type StyleResolver = (node: TraversableNode) => Record<string, unknown> | undefi
118
124
  /**
119
125
  * Recursively traverse a single node and its descendants.
120
126
  */
121
- declare function traverseNode(node: TraversableNode, context: TraversalContext, visitor: NodeVisitor, styleResolver?: StyleResolver): void;
127
+ declare function traverseNode(node: TraversableRenderable, context: TraversalContext, visitor: NodeVisitor, styleResolver?: StyleResolver, fragments?: Record<string, unknown>, fragmentStack?: string[]): void;
122
128
  /**
123
129
  * Traverse all nodes in every view of a card.
124
130
  *
125
131
  * @param views - The `views` object from a UGCCard (mapping view names to root nodes).
126
132
  * @param visitor - Called for every node in every view.
127
133
  */
128
- declare function traverseCard(views: Record<string, unknown>, visitor: NodeVisitor, styleResolver?: StyleResolver): void;
134
+ declare function traverseCard(views: Record<string, unknown>, visitor: NodeVisitor, styleResolver?: StyleResolver, fragments?: Record<string, unknown>, pathPrefix?: string): void;
129
135
 
130
136
  /**
131
137
  * @safe-ugc-ui/validator — Schema (Structural) Validation
@@ -156,6 +162,14 @@ declare function validateSchema(input: unknown): ValidationResult;
156
162
  */
157
163
  declare function parseCard(input: unknown): UGCCard | null;
158
164
 
165
+ /**
166
+ * @safe-ugc-ui/validator — Fragment Validator
167
+ *
168
+ * Validates fragment references and the non-recursive fragment rules for v0.9.
169
+ */
170
+
171
+ declare function validateFragments(views: Record<string, unknown>, fragments?: Record<string, unknown>): ValidationError[];
172
+
159
173
  /**
160
174
  * @safe-ugc-ui/validator — Node Validator
161
175
  *
@@ -178,7 +192,16 @@ declare function parseCard(input: unknown): UGCCard | null;
178
192
  * @param views - The `views` object from a UGCCard.
179
193
  * @returns An array of validation errors (empty if all nodes are valid).
180
194
  */
181
- declare function validateNodes(views: Record<string, unknown>): ValidationError[];
195
+ declare function validateNodes(views: Record<string, unknown>, fragments?: Record<string, unknown>): ValidationError[];
196
+
197
+ /**
198
+ * @safe-ugc-ui/validator — Condition Validator
199
+ *
200
+ * Validates node-level `$if` conditions that are structurally accepted by the
201
+ * schema but still need semantic guardrails such as maximum nesting depth.
202
+ */
203
+
204
+ declare function validateConditions(views: Record<string, unknown>, fragments?: Record<string, unknown>): ValidationError[];
182
205
 
183
206
  /**
184
207
  * @safe-ugc-ui/validator — Value Type Validation
@@ -210,7 +233,7 @@ declare function validateNodes(views: Record<string, unknown>): ValidationError[
210
233
  * @param views - The `views` object from a UGCCard.
211
234
  * @returns An array of validation errors (empty if all values are valid).
212
235
  */
213
- declare function validateValueTypes(views: Record<string, unknown>): ValidationError[];
236
+ declare function validateValueTypes(views: Record<string, unknown>, fragments?: Record<string, unknown>): ValidationError[];
214
237
 
215
238
  /**
216
239
  * @safe-ugc-ui/validator — Style Validator
@@ -243,7 +266,7 @@ declare function validateValueTypes(views: Record<string, unknown>): ValidationE
243
266
  * 9. Range checks on string length values
244
267
  * 10. $style reference validation and merging
245
268
  */
246
- declare function validateStyles(views: Record<string, unknown>, cardStyles?: Record<string, Record<string, unknown>>): ValidationError[];
269
+ declare function validateStyles(views: Record<string, unknown>, cardStyles?: Record<string, Record<string, unknown>>, fragments?: Record<string, unknown>): ValidationError[];
247
270
 
248
271
  /**
249
272
  * @safe-ugc-ui/validator — Security Validation
@@ -278,6 +301,7 @@ declare function validateSecurity(card: {
278
301
  state?: Record<string, unknown>;
279
302
  cardAssets?: Record<string, string>;
280
303
  cardStyles?: Record<string, Record<string, unknown>>;
304
+ fragments?: Record<string, unknown>;
281
305
  }): ValidationError[];
282
306
 
283
307
  /**
@@ -310,6 +334,7 @@ declare function validateLimits(card: {
310
334
  state?: Record<string, unknown>;
311
335
  views: Record<string, unknown>;
312
336
  cardStyles?: Record<string, Record<string, unknown>>;
337
+ fragments?: Record<string, unknown>;
313
338
  }): ValidationError[];
314
339
 
315
340
  /**
@@ -362,4 +387,4 @@ declare function validate(input: unknown): ValidationResult;
362
387
  */
363
388
  declare function validateRaw(rawJson: string): ValidationResult;
364
389
 
365
- export { type NodeVisitor, type StyleResolver, type TraversableNode, type TraversalContext, type ValidationError, type ValidationErrorCode, type ValidationResult, createError, invalidResult, merge, parseCard, toResult, traverseCard, traverseNode, validResult, validate, validateLimits, validateNodes, validateRaw, validateSchema, validateSecurity, validateStyles, validateValueTypes };
390
+ export { type NodeVisitor, type StyleResolver, type TraversableNode, type TraversalContext, type ValidationError, type ValidationErrorCode, type ValidationResult, createError, invalidResult, merge, parseCard, toResult, traverseCard, traverseNode, validResult, validate, validateConditions, validateFragments, validateLimits, validateNodes, validateRaw, validateSchema, validateSecurity, validateStyles, validateValueTypes };