@ai-matrx/content-ir 0.19.21 → 0.19.25

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.25
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/content-ir-core/v0.19.21..npm/content-ir-core/v0.19.25 -- apps/shared/content-ir-core`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.19.24
10
+
11
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
12
+ `git diff npm/content-ir-core/v0.19.21..npm/content-ir-core/v0.19.24 -- apps/shared/content-ir-core`).
13
+ No source changes intended and no consumer action required.
14
+
15
+ ## 0.19.23
16
+ ### Unreleased
17
+
18
+ - `/convert` **The control keys, one definition in two languages** (KINDS-GLUE wave 2 slice 1a). `withControlKeys(schema, { mode: "stored" | "authored", many, allowEdit })` is the byte-identical twin of aidream's `matrx_graph.kind_control_keys.with_control_keys` (shared golden `packages/matrx-graph/tests/fixtures/kind_control_keys_golden.json`): stored mode declares `_replaces` / `_new` / `_record_id` / `_records` optional and lifts the root's required Fields for a patch or a batch with one appended `allOf` branch; authored mode adds `_replaces`/`_new` always, `_record_id` only with `allowEdit`, and with `many` the root is the batch `{__kind, _records: [...]}`. `withControlKeyFields(kindSchema)` adds the four as optional render fields; `kindSchemaFromJsonSchema(kind, schema, { disposition })` applies it for `record` kinds. Consumer action: pass the registry row's `metadata.disposition` to `kindSchemaFromJsonSchema` (matrx-frontend `schema-source-kind-tables.ts`).
19
+
20
+ ## 0.19.22
21
+
22
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
23
+ `git diff npm/content-ir-core/v0.19.21..npm/content-ir-core/v0.19.22 -- apps/shared/content-ir-core`).
24
+ No source changes intended and no consumer action required.
25
+
3
26
  ## 0.19.21
4
27
  ### Unreleased
5
28
 
package/dist/convert.cjs CHANGED
@@ -425,13 +425,13 @@ function makeKindJsonSchemaProperty(kindSlug, strict) {
425
425
  return { ...base, enum: [kindSlug] };
426
426
  }
427
427
  function injectKindIntoObjectSchema(objectSchema, kindSlug, strict) {
428
- const clone = deepClone(objectSchema);
429
- const properties = isRecord(clone.properties) ? { ...clone.properties } : {};
428
+ const clone2 = deepClone(objectSchema);
429
+ const properties = isRecord(clone2.properties) ? { ...clone2.properties } : {};
430
430
  properties[KIND_KEY] = makeKindJsonSchemaProperty(kindSlug, strict);
431
- const required = Array.isArray(clone.required) ? clone.required.filter((k) => typeof k === "string") : [];
431
+ const required = Array.isArray(clone2.required) ? clone2.required.filter((k) => typeof k === "string") : [];
432
432
  const nextRequired = required.includes(KIND_KEY) ? required : [KIND_KEY, ...required];
433
433
  return {
434
- ...clone,
434
+ ...clone2,
435
435
  properties,
436
436
  required: nextRequired,
437
437
  ...strict ? { additionalProperties: false } : {}
@@ -1628,8 +1628,132 @@ function kindSchemaToJsonSchema(kind, resolve, options = {}) {
1628
1628
  return { name: kind, schema: { ...rootNode, $defs: defs }, strict, unresolved };
1629
1629
  }
1630
1630
 
1631
+ // convert/control-keys.ts
1632
+ var CONTROL_KEYS = ["_replaces", "_new", "_record_id", "_records"];
1633
+ var RECORD_DISPOSITION = "record";
1634
+ var KIND_KEY2 = "__kind";
1635
+ var DOCUMENT_KEYS = /* @__PURE__ */ new Set(["$schema", "$id", "$defs", "definitions", "title", "description"]);
1636
+ var CONTROL = new Set(CONTROL_KEYS);
1637
+ function controlKeysApplyTo(disposition) {
1638
+ return disposition === RECORD_DISPOSITION;
1639
+ }
1640
+ function clone(value) {
1641
+ return value === void 0 ? value : JSON.parse(JSON.stringify(value));
1642
+ }
1643
+ function isObjectSchema(schema) {
1644
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) return false;
1645
+ const s = schema;
1646
+ return s.type === "object" && !!s.properties && typeof s.properties === "object" && !Array.isArray(s.properties);
1647
+ }
1648
+ function requiredOf(schema) {
1649
+ return Array.isArray(schema.required) ? schema.required : [];
1650
+ }
1651
+ function recordObject(schema) {
1652
+ const item = {};
1653
+ for (const [k, v] of Object.entries(schema)) {
1654
+ if (!DOCUMENT_KEYS.has(k)) item[k] = clone(v);
1655
+ }
1656
+ const props = {};
1657
+ for (const [k, v] of Object.entries(item.properties)) {
1658
+ if (k !== KIND_KEY2 && !CONTROL.has(k)) props[k] = v;
1659
+ }
1660
+ item.properties = props;
1661
+ const required = requiredOf(item).filter((k) => k !== KIND_KEY2 && !CONTROL.has(k));
1662
+ if (required.length > 0) item.required = required;
1663
+ else delete item.required;
1664
+ return item;
1665
+ }
1666
+ function stored(schema) {
1667
+ const out = clone(schema);
1668
+ const item = recordObject(schema);
1669
+ const props = out.properties;
1670
+ props._replaces = { type: ["string", "null"], format: "uuid" };
1671
+ props._new = { type: ["boolean", "null"] };
1672
+ props._record_id = { type: ["string", "null"], format: "uuid" };
1673
+ props._records = { type: ["array", "null"], items: item };
1674
+ const rootRequired = requiredOf(out).filter((k) => !CONTROL.has(k));
1675
+ const lifted = rootRequired.filter((k) => k !== KIND_KEY2);
1676
+ if (lifted.length > 0) {
1677
+ const kept = rootRequired.filter((k) => k === KIND_KEY2);
1678
+ if (kept.length > 0) out.required = kept;
1679
+ else delete out.required;
1680
+ const branch = {
1681
+ if: {
1682
+ anyOf: [
1683
+ { required: ["_record_id"], properties: { _record_id: { type: "string" } } },
1684
+ { required: ["_records"], properties: { _records: { type: "array" } } }
1685
+ ]
1686
+ },
1687
+ else: { required: lifted }
1688
+ };
1689
+ out.allOf = Array.isArray(out.allOf) ? [...out.allOf, branch] : [branch];
1690
+ }
1691
+ return out;
1692
+ }
1693
+ function authored(schema, many, allowEdit) {
1694
+ const signals = {
1695
+ _replaces: { type: "string", format: "uuid" },
1696
+ _new: { type: "boolean" }
1697
+ };
1698
+ if (allowEdit) signals._record_id = { type: "string", format: "uuid" };
1699
+ if (!many) {
1700
+ const out2 = clone(schema);
1701
+ Object.assign(out2.properties, clone(signals));
1702
+ const required = requiredOf(out2).filter((k) => !CONTROL.has(k));
1703
+ if (required.length > 0 || "required" in out2) out2.required = required;
1704
+ return out2;
1705
+ }
1706
+ const out = {};
1707
+ for (const [k, v] of Object.entries(schema)) {
1708
+ if (DOCUMENT_KEYS.has(k)) out[k] = clone(v);
1709
+ }
1710
+ out.type = "object";
1711
+ const kindProp = schema.properties[KIND_KEY2];
1712
+ const properties = {};
1713
+ if (kindProp !== void 0) properties[KIND_KEY2] = clone(kindProp);
1714
+ properties._records = { type: "array", items: recordObject(schema) };
1715
+ Object.assign(properties, clone(signals));
1716
+ out.properties = properties;
1717
+ out.required = [KIND_KEY2, "_records"].filter((k) => k in properties);
1718
+ out.additionalProperties = false;
1719
+ return out;
1720
+ }
1721
+ function withControlKeys(schema, options) {
1722
+ const { mode, many = false, allowEdit = false } = options;
1723
+ if (mode !== "stored" && mode !== "authored") {
1724
+ throw new Error(`withControlKeys: mode must be "stored" or "authored", got ${String(mode)}`);
1725
+ }
1726
+ if (!isObjectSchema(schema)) return schema;
1727
+ return mode === "stored" ? stored(schema) : authored(schema, many, allowEdit);
1728
+ }
1729
+ var CONTROL_KEY_FIELDS = Object.freeze({
1730
+ _replaces: { type: "string", nullable: true },
1731
+ _new: { type: "boolean", nullable: true },
1732
+ _record_id: { type: "string", nullable: true },
1733
+ // A batch's items are records of this kind WITHOUT `__kind`; the render layer reads them
1734
+ // as opaque JSON (never stricter than the store, which validates each item).
1735
+ _records: { type: "json[]", nullable: true }
1736
+ });
1737
+ function withControlKeyFields(schema) {
1738
+ if (schema.root) return schema;
1739
+ const fields = { ...schema.fields };
1740
+ for (const key of CONTROL_KEYS) {
1741
+ if (!(key in fields)) fields[key] = { ...CONTROL_KEY_FIELDS[key] };
1742
+ }
1743
+ return { ...schema, fields };
1744
+ }
1745
+ function stripControlKeys(value) {
1746
+ const values = {};
1747
+ const signals = {};
1748
+ for (const [k, v] of Object.entries(value)) {
1749
+ if (CONTROL.has(k)) signals[k] = v;
1750
+ else values[k] = v;
1751
+ }
1752
+ return { values, signals };
1753
+ }
1754
+
1631
1755
  // convert/json-schema-to-kind.ts
1632
- function kindSchemaFromJsonSchema(kind, jsonSchema) {
1756
+ function kindSchemaFromJsonSchema(kind, jsonSchema, options = {}) {
1633
1757
  if (jsonSchema === null || jsonSchema === void 0) {
1634
1758
  return { schema: null, children: {}, problems: [] };
1635
1759
  }
@@ -1660,13 +1784,20 @@ function kindSchemaFromJsonSchema(kind, jsonSchema) {
1660
1784
  if (draft.slug === kind) schema = asKindSchema;
1661
1785
  else children[draft.slug] = asKindSchema;
1662
1786
  }
1787
+ if (schema && controlKeysApplyTo(options.disposition)) {
1788
+ schema = withControlKeyFields(schema);
1789
+ }
1663
1790
  return { schema, children, problems: converted.problems };
1664
1791
  }
1665
1792
 
1793
+ exports.CONTROL_KEYS = CONTROL_KEYS;
1794
+ exports.CONTROL_KEY_FIELDS = CONTROL_KEY_FIELDS;
1795
+ exports.RECORD_DISPOSITION = RECORD_DISPOSITION;
1666
1796
  exports.buildAgentSchemaWithRenderBlockSupport = buildAgentSchemaWithRenderBlockSupport;
1667
1797
  exports.collectReferencedKinds = collectReferencedKinds;
1668
1798
  exports.collectSchemaReferencedKinds = collectSchemaReferencedKinds;
1669
1799
  exports.compareWithExistingKindSchema = compareWithExistingKindSchema;
1800
+ exports.controlKeysApplyTo = controlKeysApplyTo;
1670
1801
  exports.convertAiSchemaToBlockFields = convertAiSchemaToBlockFields;
1671
1802
  exports.fieldsToDbPayload = fieldsToDbPayload;
1672
1803
  exports.injectKindIntoObjectSchema = injectKindIntoObjectSchema;
@@ -1675,6 +1806,9 @@ exports.kindSchemaFromJsonSchema = kindSchemaFromJsonSchema;
1675
1806
  exports.kindSchemaToJsonSchema = kindSchemaToJsonSchema;
1676
1807
  exports.normalizeAiSchemaInput = normalizeAiSchemaInput;
1677
1808
  exports.runSchemaConversion = runSchemaConversion;
1809
+ exports.stripControlKeys = stripControlKeys;
1678
1810
  exports.validateBlockSchemaSavePlan = validateBlockSchemaSavePlan;
1811
+ exports.withControlKeyFields = withControlKeyFields;
1812
+ exports.withControlKeys = withControlKeys;
1679
1813
  //# sourceMappingURL=convert.cjs.map
1680
1814
  //# sourceMappingURL=convert.cjs.map