@safe-ugc-ui/validator 0.5.1 → 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,31 +99,39 @@ 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
+ responsive?: Record<string, unknown>;
104
105
  [key: string]: unknown;
105
106
  }
107
+ interface FragmentUseLike {
108
+ $use: string;
109
+ $if?: unknown;
110
+ [key: string]: unknown;
111
+ }
112
+ type TraversableRenderable = TraversableNode | FragmentUseLike;
106
113
  interface ForLoopLike {
107
114
  for: string;
108
115
  in: string;
109
- template: TraversableNode;
116
+ template: TraversableRenderable;
110
117
  }
111
118
  /**
112
119
  * A visitor function called for every node in the tree.
113
120
  * Return `false` to skip traversing into this node's children.
114
121
  */
115
122
  type NodeVisitor = (node: TraversableNode, context: TraversalContext) => void | false;
123
+ type StyleResolver = (node: TraversableNode) => Record<string, unknown> | undefined;
116
124
  /**
117
125
  * Recursively traverse a single node and its descendants.
118
126
  */
119
- declare function traverseNode(node: TraversableNode, context: TraversalContext, visitor: NodeVisitor): void;
127
+ declare function traverseNode(node: TraversableRenderable, context: TraversalContext, visitor: NodeVisitor, styleResolver?: StyleResolver, fragments?: Record<string, unknown>, fragmentStack?: string[]): void;
120
128
  /**
121
129
  * Traverse all nodes in every view of a card.
122
130
  *
123
131
  * @param views - The `views` object from a UGCCard (mapping view names to root nodes).
124
132
  * @param visitor - Called for every node in every view.
125
133
  */
126
- declare function traverseCard(views: Record<string, unknown>, visitor: NodeVisitor): void;
134
+ declare function traverseCard(views: Record<string, unknown>, visitor: NodeVisitor, styleResolver?: StyleResolver, fragments?: Record<string, unknown>, pathPrefix?: string): void;
127
135
 
128
136
  /**
129
137
  * @safe-ugc-ui/validator — Schema (Structural) Validation
@@ -154,6 +162,14 @@ declare function validateSchema(input: unknown): ValidationResult;
154
162
  */
155
163
  declare function parseCard(input: unknown): UGCCard | null;
156
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
+
157
173
  /**
158
174
  * @safe-ugc-ui/validator — Node Validator
159
175
  *
@@ -176,7 +192,16 @@ declare function parseCard(input: unknown): UGCCard | null;
176
192
  * @param views - The `views` object from a UGCCard.
177
193
  * @returns An array of validation errors (empty if all nodes are valid).
178
194
  */
179
- 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[];
180
205
 
181
206
  /**
182
207
  * @safe-ugc-ui/validator — Value Type Validation
@@ -208,7 +233,7 @@ declare function validateNodes(views: Record<string, unknown>): ValidationError[
208
233
  * @param views - The `views` object from a UGCCard.
209
234
  * @returns An array of validation errors (empty if all values are valid).
210
235
  */
211
- declare function validateValueTypes(views: Record<string, unknown>): ValidationError[];
236
+ declare function validateValueTypes(views: Record<string, unknown>, fragments?: Record<string, unknown>): ValidationError[];
212
237
 
213
238
  /**
214
239
  * @safe-ugc-ui/validator — Style Validator
@@ -241,7 +266,7 @@ declare function validateValueTypes(views: Record<string, unknown>): ValidationE
241
266
  * 9. Range checks on string length values
242
267
  * 10. $style reference validation and merging
243
268
  */
244
- 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[];
245
270
 
246
271
  /**
247
272
  * @safe-ugc-ui/validator — Security Validation
@@ -276,6 +301,7 @@ declare function validateSecurity(card: {
276
301
  state?: Record<string, unknown>;
277
302
  cardAssets?: Record<string, string>;
278
303
  cardStyles?: Record<string, Record<string, unknown>>;
304
+ fragments?: Record<string, unknown>;
279
305
  }): ValidationError[];
280
306
 
281
307
  /**
@@ -308,6 +334,7 @@ declare function validateLimits(card: {
308
334
  state?: Record<string, unknown>;
309
335
  views: Record<string, unknown>;
310
336
  cardStyles?: Record<string, Record<string, unknown>>;
337
+ fragments?: Record<string, unknown>;
311
338
  }): ValidationError[];
312
339
 
313
340
  /**
@@ -360,4 +387,4 @@ declare function validate(input: unknown): ValidationResult;
360
387
  */
361
388
  declare function validateRaw(rawJson: string): ValidationResult;
362
389
 
363
- export { type NodeVisitor, 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 };