@jxsuite/schema 0.28.5 → 0.29.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.
@@ -15,11 +15,19 @@ export const arrayNamespaceSchema = {
15
15
  } as const;
16
16
 
17
17
  export const childrenValueSchema = {
18
- description: "Static array of child definitions, or an Array namespace for dynamic lists.",
18
+ description:
19
+ "Array of child definitions — elements, text, or Array namespaces (dynamic lists) mixed " +
20
+ "freely. A bare Array namespace (the whole children slot is one dynamic list) is also " +
21
+ "accepted for backward compatibility.",
19
22
  oneOf: [
20
23
  {
21
24
  items: {
22
- oneOf: [{ $ref: "#/$defs/ElementDef" }, { type: "string" }, { type: "number" }],
25
+ oneOf: [
26
+ { $ref: "#/$defs/ElementDef" },
27
+ { $ref: "#/$defs/ArrayNamespace" },
28
+ { type: "string" },
29
+ { type: "number" },
30
+ ],
23
31
  },
24
32
  type: "array",
25
33
  },
package/package.json CHANGED
@@ -39,7 +39,7 @@
39
39
  "upgrade": "bunx npm-check-updates -u && bun install"
40
40
  },
41
41
  "type": "module",
42
- "version": "0.28.5",
42
+ "version": "0.29.0",
43
43
  "devDependencies": {
44
44
  "json-schema-to-ts": "^3.1.1"
45
45
  }
package/schema.json CHANGED
@@ -4665,7 +4665,7 @@
4665
4665
  "type": "object"
4666
4666
  },
4667
4667
  "ChildrenValue": {
4668
- "description": "Static array of child definitions, or an Array namespace for dynamic lists.",
4668
+ "description": "Array of child definitions — elements, text, or Array namespaces (dynamic lists) mixed freely. A bare Array namespace (the whole children slot is one dynamic list) is also accepted for backward compatibility.",
4669
4669
  "oneOf": [
4670
4670
  {
4671
4671
  "items": {
@@ -4673,6 +4673,9 @@
4673
4673
  {
4674
4674
  "$ref": "#/$defs/ElementDef"
4675
4675
  },
4676
+ {
4677
+ "$ref": "#/$defs/ArrayNamespace"
4678
+ },
4676
4679
  {
4677
4680
  "type": "string"
4678
4681
  },
package/src/guards.ts CHANGED
@@ -126,6 +126,18 @@ export function isMappedArray(value: unknown): value is JxMappedArray {
126
126
  return isJsonObject(value) && value.$prototype === "Array";
127
127
  }
128
128
 
129
+ /**
130
+ * Whether a node's `children` holds at least one mapped array — either as the bare whole-children
131
+ * slot (legacy) or as a member of the children array. Used by renderers and the compiler to decide
132
+ * if a children list needs inline repeater expansion.
133
+ */
134
+ export function childrenContainArray(children?: unknown): boolean {
135
+ if (isMappedArray(children)) {
136
+ return true;
137
+ }
138
+ return Array.isArray(children) && children.some((c) => isMappedArray(c));
139
+ }
140
+
129
141
  /** A .class.json schema-defined class document — `{ $prototype: "Class" }`. */
130
142
  export function isClassDef(value: unknown): value is JxClassDef {
131
143
  return isJsonObject(value) && value.$prototype === "Class";
package/src/schema.ts CHANGED
@@ -487,13 +487,29 @@ export async function generateSchemaString() {
487
487
  return JSON.stringify(await generateSchema(), null, 2);
488
488
  }
489
489
 
490
+ // Minimal structural types for the optional `ajv` / `ajv-formats` peer deps
491
+ // (not installed, and shipping no types, in this repo).
492
+ interface AjvValidateFn {
493
+ (doc: unknown): boolean;
494
+ errors?: unknown[] | null;
495
+ }
496
+ interface AjvInstance {
497
+ compile: (schema: unknown) => AjvValidateFn;
498
+ }
499
+ type AjvCtor = new (opts: {
500
+ allErrors: boolean;
501
+ ownProperties: boolean;
502
+ strict: boolean;
503
+ }) => AjvInstance;
504
+ type AddFormatsFn = (ajv: AjvInstance) => void;
505
+
490
506
  export async function validateDocument(doc: Record<string, unknown>) {
491
- let Ajv, addFormats;
507
+ let Ajv: AjvCtor, addFormats: AddFormatsFn;
492
508
  try {
493
509
  // @ts-expect-error — optional peer dependency
494
- ({ default: Ajv } = await import("ajv"));
510
+ ({ default: Ajv } = (await import("ajv")) as { default: AjvCtor });
495
511
  // @ts-expect-error — optional peer dependency
496
- ({ default: addFormats } = await import("ajv-formats"));
512
+ ({ default: addFormats } = (await import("ajv-formats")) as { default: AddFormatsFn });
497
513
  } catch {
498
514
  throw new Error("Schema validation requires ajv and ajv-formats: bun add ajv ajv-formats");
499
515
  }
package/types.ts CHANGED
@@ -198,6 +198,13 @@ export interface JxElement {
198
198
  tagName?: string;
199
199
  textContent?: string | null | JxRef;
200
200
  innerHTML?: string;
201
+ /**
202
+ * Child nodes. A repeater (`{ $prototype: "Array", … }`) may appear as a member of the array —
203
+ * nestled among siblings or as the sole child — and is structurally a `JxElement` (its
204
+ * `items`/`map`/`filter`/`sort` are absorbed by the open index signature; narrow with
205
+ * `isMappedArray`). The bare `| JxMappedArray` form (whole children slot is one repeater) is
206
+ * retained for backward compatibility with legacy docs.
207
+ */
201
208
  children?: (JxElement | string)[] | JxMappedArray;
202
209
  style?: JxStyle;
203
210
  attributes?: Record<string, JxAttributeValue>;
@@ -471,6 +478,12 @@ export interface JxMutableNode {
471
478
  tagName?: string;
472
479
  textContent?: string | null | JxRef;
473
480
  innerHTML?: string;
481
+ /**
482
+ * Child nodes. The editor models a mapped-array (repeater) member as a `JxMutableNode` carrying
483
+ * `$prototype: "Array"` (plus `items`/`map`/`filter`/`sort` below), so members stay assignable
484
+ * here. The bare `| JxMappedArray` form (whole children slot is one repeater) is retained for
485
+ * backward compatibility.
486
+ */
474
487
  children?: (JxMutableNode | string)[] | JxMappedArray;
475
488
  style?: JxStyle;
476
489
  attributes?: Record<string, JxAttributeValue>;