@safe-ugc-ui/validator 0.3.1 → 0.5.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' | 'EXPR_NOT_ALLOWED' | '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' | 'EXPR_TOO_LONG' | 'REF_TOO_LONG' | 'EXPR_TOO_MANY_TOKENS' | 'EXPR_NESTING_TOO_DEEP' | 'EXPR_CONDITION_NESTING_TOO_DEEP' | 'EXPR_REF_DEPTH_EXCEEDED' | 'EXPR_ARRAY_INDEX_EXCEEDED' | 'EXPR_STRING_LITERAL_TOO_LONG' | 'EXPR_FORBIDDEN_TOKEN' | 'EXPR_FUNCTION_CALL' | 'EXPR_INVALID_TOKEN' | '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' | 'INVALID_HOVER_STYLE' | 'HOVER_STYLE_NESTED' | 'TRANSITION_RAW_STRING' | 'TRANSITION_COUNT_EXCEEDED' | 'TRANSITION_PROPERTY_FORBIDDEN';
18
18
  /**
19
19
  * A single validation error with location and diagnostic info.
20
20
  */
@@ -101,7 +101,6 @@ interface TraversableNode {
101
101
  type: string;
102
102
  children?: TraversableNode[] | ForLoopLike;
103
103
  style?: Record<string, unknown>;
104
- condition?: unknown;
105
104
  [key: string]: unknown;
106
105
  }
107
106
  interface ForLoopLike {
@@ -182,29 +181,29 @@ declare function validateNodes(views: Record<string, unknown>): ValidationError[
182
181
  /**
183
182
  * @safe-ugc-ui/validator — Value Type Validation
184
183
  *
185
- * Validates per-property $ref / $expr permission rules based on spec
184
+ * Validates per-property $ref permission rules based on spec
186
185
  * section 4.5 value type table.
187
186
  *
188
- * | Property Type | Literal | $ref | $expr |
189
- * |-------------------|---------|------|-------|
190
- * | Image.src | yes | yes | no |
191
- * | Avatar.src | yes | yes | no |
192
- * | Icon.name | yes | no | no |
193
- * | Text.content | yes | yes | yes |
194
- * | Color properties | yes | yes | yes |
195
- * | Size properties | yes | yes | yes |
196
- * | position | yes | no | no |
197
- * | transform | yes | no | no |
198
- * | gradient | yes | no | no |
199
- *
200
- * Additionally, several style properties must always be static
201
- * (no $ref or $expr): overflow, border*, boxShadow, zIndex,
202
- * and position offset properties (top/right/bottom/left).
187
+ * | Property Type | Literal | $ref |
188
+ * |-------------------|---------|------|
189
+ * | Image.src | yes | yes |
190
+ * | Avatar.src | yes | yes |
191
+ * | Icon.name | yes | yes |
192
+ * | Text.content | yes | yes |
193
+ * | Color properties | yes | yes |
194
+ * | Size properties | yes | yes |
195
+ * | position | yes | no |
196
+ * | overflow | yes | no |
197
+ * | zIndex | yes | no |
198
+ * | structured style objects | object literal | top-level $ref no |
199
+ *
200
+ * Structured style objects such as border/transform/boxShadow/textShadow/backgroundGradient
201
+ * must remain object literals, but selected leaf fields inside them may use $ref.
203
202
  */
204
203
 
205
204
  /**
206
205
  * Walk all nodes in the card and validate that each field's value
207
- * respects its allowed value types ($ref / $expr permissions).
206
+ * respects its allowed value types ($ref permissions).
208
207
  *
209
208
  * @param views - The `views` object from a UGCCard.
210
209
  * @returns An array of validation errors (empty if all values are valid).
@@ -217,6 +216,7 @@ declare function validateValueTypes(views: Record<string, unknown>): ValidationE
217
216
  * Validates style properties according to the spec's style restrictions:
218
217
  * - Forbidden CSS properties (spec 3.8)
219
218
  * - Numeric range limits (spec 6.4)
219
+ * - Text-shadow count and value limits
220
220
  * - Box-shadow count and value limits
221
221
  * - Transform skew prohibition
222
222
  * - Dangerous CSS function injection detection
@@ -310,28 +310,6 @@ declare function validateLimits(card: {
310
310
  cardStyles?: Record<string, Record<string, unknown>>;
311
311
  }): ValidationError[];
312
312
 
313
- /**
314
- * @safe-ugc-ui/validator -- Expression & Reference Constraint Validation
315
- *
316
- * Validates $expr and $ref values found in the card tree against the
317
- * constraints defined in the spec's "expression constraint" section (6.3).
318
- *
319
- * A simple tokenizer splits expression strings into typed tokens so that
320
- * structural limits (nesting, token count, forbidden operators) can be
321
- * checked without executing the expression.
322
- */
323
-
324
- /**
325
- * Validates all $expr and $ref values found in the card's views.
326
- *
327
- * Uses tree traversal to visit every node, then deep-scans each node's
328
- * flattened node fields and `style` (and `condition`) for dynamic values.
329
- *
330
- * @param views - The `views` object from a UGCCard.
331
- * @returns An array of validation errors (empty if all constraints pass).
332
- */
333
- declare function validateExprConstraints(views: Record<string, unknown>): ValidationError[];
334
-
335
313
  /**
336
314
  * @safe-ugc-ui/validator — Public API
337
315
  *
@@ -349,7 +327,7 @@ declare function validateExprConstraints(views: Record<string, unknown>): Valida
349
327
  * 2. (validateRaw only) JSON.parse — parse error → ValidationResult
350
328
  * 3. Schema validation → fail → early return
351
329
  * 4. All remaining checks run, errors accumulated:
352
- * node → value-types → style → security → limits → expr-constraints
330
+ * node → value-types → style → security → limits
353
331
  */
354
332
 
355
333
  /**
@@ -359,7 +337,7 @@ declare function validateExprConstraints(views: Record<string, unknown>): Valida
359
337
  *
360
338
  * Pipeline:
361
339
  * 1. Schema validation → fail → early return
362
- * 2. All remaining checks (node, value-types, style, security, limits, expr)
340
+ * 2. All remaining checks (node, value-types, style, security, limits)
363
341
  *
364
342
  * @param input - An unknown value (typically parsed JSON).
365
343
  * @returns A ValidationResult — safe to render only if `valid` is true.
@@ -382,4 +360,4 @@ declare function validate(input: unknown): ValidationResult;
382
360
  */
383
361
  declare function validateRaw(rawJson: string): ValidationResult;
384
362
 
385
- export { type NodeVisitor, type TraversableNode, type TraversalContext, type ValidationError, type ValidationErrorCode, type ValidationResult, createError, invalidResult, merge, parseCard, toResult, traverseCard, traverseNode, validResult, validate, validateExprConstraints, validateLimits, validateNodes, validateRaw, validateSchema, validateSecurity, validateStyles, validateValueTypes };
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 };