@ai-matrx/content-ir 0.19.21 → 0.19.26

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,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.26
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/content-ir-core/v0.19.25..npm/content-ir-core/v0.19.26 -- apps/shared/content-ir-core`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.19.25
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.25 -- apps/shared/content-ir-core`).
13
+ No source changes intended and no consumer action required.
14
+
15
+ ## 0.19.24
16
+
17
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
18
+ `git diff npm/content-ir-core/v0.19.21..npm/content-ir-core/v0.19.24 -- apps/shared/content-ir-core`).
19
+ No source changes intended and no consumer action required.
20
+
21
+ ## 0.19.23
22
+ ### Unreleased
23
+
24
+ - `/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`).
25
+
26
+ ## 0.19.22
27
+
28
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
29
+ `git diff npm/content-ir-core/v0.19.21..npm/content-ir-core/v0.19.22 -- apps/shared/content-ir-core`).
30
+ No source changes intended and no consumer action required.
31
+
3
32
  ## 0.19.21
4
33
  ### Unreleased
5
34
 
package/dist/convert.cjs CHANGED
@@ -8,7 +8,7 @@ function scalarArrayItemType(type) {
8
8
  return "string";
9
9
  }
10
10
 
11
- // utils/text-case-converter.ts
11
+ // text-case.ts
12
12
  var DEFAULT_WORD_REPLACEMENTS = {
13
13
  // Acronyms & initialisms
14
14
  "api": "API",
@@ -276,6 +276,24 @@ function formatText(text, options = {}) {
276
276
  }
277
277
  return result;
278
278
  }
279
+ var IDENTIFIER_ACRONYMS = [
280
+ "ID",
281
+ "URL",
282
+ "PDF",
283
+ "HTML",
284
+ "JSON",
285
+ "API",
286
+ "AI",
287
+ "UI",
288
+ "CSV",
289
+ "SMS",
290
+ "SEO",
291
+ "LLM",
292
+ "MCP",
293
+ "UUID",
294
+ "ISO"
295
+ ];
296
+ new Set(IDENTIFIER_ACRONYMS.map((a) => a.toLowerCase()));
279
297
 
280
298
  // core/schema-structure.ts
281
299
  function formatBlockLabel(key) {
@@ -425,13 +443,13 @@ function makeKindJsonSchemaProperty(kindSlug, strict) {
425
443
  return { ...base, enum: [kindSlug] };
426
444
  }
427
445
  function injectKindIntoObjectSchema(objectSchema, kindSlug, strict) {
428
- const clone = deepClone(objectSchema);
429
- const properties = isRecord(clone.properties) ? { ...clone.properties } : {};
446
+ const clone2 = deepClone(objectSchema);
447
+ const properties = isRecord(clone2.properties) ? { ...clone2.properties } : {};
430
448
  properties[KIND_KEY] = makeKindJsonSchemaProperty(kindSlug, strict);
431
- const required = Array.isArray(clone.required) ? clone.required.filter((k) => typeof k === "string") : [];
449
+ const required = Array.isArray(clone2.required) ? clone2.required.filter((k) => typeof k === "string") : [];
432
450
  const nextRequired = required.includes(KIND_KEY) ? required : [KIND_KEY, ...required];
433
451
  return {
434
- ...clone,
452
+ ...clone2,
435
453
  properties,
436
454
  required: nextRequired,
437
455
  ...strict ? { additionalProperties: false } : {}
@@ -1628,8 +1646,132 @@ function kindSchemaToJsonSchema(kind, resolve, options = {}) {
1628
1646
  return { name: kind, schema: { ...rootNode, $defs: defs }, strict, unresolved };
1629
1647
  }
1630
1648
 
1649
+ // convert/control-keys.ts
1650
+ var CONTROL_KEYS = ["_replaces", "_new", "_record_id", "_records"];
1651
+ var RECORD_DISPOSITION = "record";
1652
+ var KIND_KEY2 = "__kind";
1653
+ var DOCUMENT_KEYS = /* @__PURE__ */ new Set(["$schema", "$id", "$defs", "definitions", "title", "description"]);
1654
+ var CONTROL = new Set(CONTROL_KEYS);
1655
+ function controlKeysApplyTo(disposition) {
1656
+ return disposition === RECORD_DISPOSITION;
1657
+ }
1658
+ function clone(value) {
1659
+ return value === void 0 ? value : JSON.parse(JSON.stringify(value));
1660
+ }
1661
+ function isObjectSchema(schema) {
1662
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) return false;
1663
+ const s = schema;
1664
+ return s.type === "object" && !!s.properties && typeof s.properties === "object" && !Array.isArray(s.properties);
1665
+ }
1666
+ function requiredOf(schema) {
1667
+ return Array.isArray(schema.required) ? schema.required : [];
1668
+ }
1669
+ function recordObject(schema) {
1670
+ const item = {};
1671
+ for (const [k, v] of Object.entries(schema)) {
1672
+ if (!DOCUMENT_KEYS.has(k)) item[k] = clone(v);
1673
+ }
1674
+ const props = {};
1675
+ for (const [k, v] of Object.entries(item.properties)) {
1676
+ if (k !== KIND_KEY2 && !CONTROL.has(k)) props[k] = v;
1677
+ }
1678
+ item.properties = props;
1679
+ const required = requiredOf(item).filter((k) => k !== KIND_KEY2 && !CONTROL.has(k));
1680
+ if (required.length > 0) item.required = required;
1681
+ else delete item.required;
1682
+ return item;
1683
+ }
1684
+ function stored(schema) {
1685
+ const out = clone(schema);
1686
+ const item = recordObject(schema);
1687
+ const props = out.properties;
1688
+ props._replaces = { type: ["string", "null"], format: "uuid" };
1689
+ props._new = { type: ["boolean", "null"] };
1690
+ props._record_id = { type: ["string", "null"], format: "uuid" };
1691
+ props._records = { type: ["array", "null"], items: item };
1692
+ const rootRequired = requiredOf(out).filter((k) => !CONTROL.has(k));
1693
+ const lifted = rootRequired.filter((k) => k !== KIND_KEY2);
1694
+ if (lifted.length > 0) {
1695
+ const kept = rootRequired.filter((k) => k === KIND_KEY2);
1696
+ if (kept.length > 0) out.required = kept;
1697
+ else delete out.required;
1698
+ const branch = {
1699
+ if: {
1700
+ anyOf: [
1701
+ { required: ["_record_id"], properties: { _record_id: { type: "string" } } },
1702
+ { required: ["_records"], properties: { _records: { type: "array" } } }
1703
+ ]
1704
+ },
1705
+ else: { required: lifted }
1706
+ };
1707
+ out.allOf = Array.isArray(out.allOf) ? [...out.allOf, branch] : [branch];
1708
+ }
1709
+ return out;
1710
+ }
1711
+ function authored(schema, many, allowEdit) {
1712
+ const signals = {
1713
+ _replaces: { type: "string", format: "uuid" },
1714
+ _new: { type: "boolean" }
1715
+ };
1716
+ if (allowEdit) signals._record_id = { type: "string", format: "uuid" };
1717
+ if (!many) {
1718
+ const out2 = clone(schema);
1719
+ Object.assign(out2.properties, clone(signals));
1720
+ const required = requiredOf(out2).filter((k) => !CONTROL.has(k));
1721
+ if (required.length > 0 || "required" in out2) out2.required = required;
1722
+ return out2;
1723
+ }
1724
+ const out = {};
1725
+ for (const [k, v] of Object.entries(schema)) {
1726
+ if (DOCUMENT_KEYS.has(k)) out[k] = clone(v);
1727
+ }
1728
+ out.type = "object";
1729
+ const kindProp = schema.properties[KIND_KEY2];
1730
+ const properties = {};
1731
+ if (kindProp !== void 0) properties[KIND_KEY2] = clone(kindProp);
1732
+ properties._records = { type: "array", items: recordObject(schema) };
1733
+ Object.assign(properties, clone(signals));
1734
+ out.properties = properties;
1735
+ out.required = [KIND_KEY2, "_records"].filter((k) => k in properties);
1736
+ out.additionalProperties = false;
1737
+ return out;
1738
+ }
1739
+ function withControlKeys(schema, options) {
1740
+ const { mode, many = false, allowEdit = false } = options;
1741
+ if (mode !== "stored" && mode !== "authored") {
1742
+ throw new Error(`withControlKeys: mode must be "stored" or "authored", got ${String(mode)}`);
1743
+ }
1744
+ if (!isObjectSchema(schema)) return schema;
1745
+ return mode === "stored" ? stored(schema) : authored(schema, many, allowEdit);
1746
+ }
1747
+ var CONTROL_KEY_FIELDS = Object.freeze({
1748
+ _replaces: { type: "string", nullable: true },
1749
+ _new: { type: "boolean", nullable: true },
1750
+ _record_id: { type: "string", nullable: true },
1751
+ // A batch's items are records of this kind WITHOUT `__kind`; the render layer reads them
1752
+ // as opaque JSON (never stricter than the store, which validates each item).
1753
+ _records: { type: "json[]", nullable: true }
1754
+ });
1755
+ function withControlKeyFields(schema) {
1756
+ if (schema.root) return schema;
1757
+ const fields = { ...schema.fields };
1758
+ for (const key of CONTROL_KEYS) {
1759
+ if (!(key in fields)) fields[key] = { ...CONTROL_KEY_FIELDS[key] };
1760
+ }
1761
+ return { ...schema, fields };
1762
+ }
1763
+ function stripControlKeys(value) {
1764
+ const values = {};
1765
+ const signals = {};
1766
+ for (const [k, v] of Object.entries(value)) {
1767
+ if (CONTROL.has(k)) signals[k] = v;
1768
+ else values[k] = v;
1769
+ }
1770
+ return { values, signals };
1771
+ }
1772
+
1631
1773
  // convert/json-schema-to-kind.ts
1632
- function kindSchemaFromJsonSchema(kind, jsonSchema) {
1774
+ function kindSchemaFromJsonSchema(kind, jsonSchema, options = {}) {
1633
1775
  if (jsonSchema === null || jsonSchema === void 0) {
1634
1776
  return { schema: null, children: {}, problems: [] };
1635
1777
  }
@@ -1660,13 +1802,20 @@ function kindSchemaFromJsonSchema(kind, jsonSchema) {
1660
1802
  if (draft.slug === kind) schema = asKindSchema;
1661
1803
  else children[draft.slug] = asKindSchema;
1662
1804
  }
1805
+ if (schema && controlKeysApplyTo(options.disposition)) {
1806
+ schema = withControlKeyFields(schema);
1807
+ }
1663
1808
  return { schema, children, problems: converted.problems };
1664
1809
  }
1665
1810
 
1811
+ exports.CONTROL_KEYS = CONTROL_KEYS;
1812
+ exports.CONTROL_KEY_FIELDS = CONTROL_KEY_FIELDS;
1813
+ exports.RECORD_DISPOSITION = RECORD_DISPOSITION;
1666
1814
  exports.buildAgentSchemaWithRenderBlockSupport = buildAgentSchemaWithRenderBlockSupport;
1667
1815
  exports.collectReferencedKinds = collectReferencedKinds;
1668
1816
  exports.collectSchemaReferencedKinds = collectSchemaReferencedKinds;
1669
1817
  exports.compareWithExistingKindSchema = compareWithExistingKindSchema;
1818
+ exports.controlKeysApplyTo = controlKeysApplyTo;
1670
1819
  exports.convertAiSchemaToBlockFields = convertAiSchemaToBlockFields;
1671
1820
  exports.fieldsToDbPayload = fieldsToDbPayload;
1672
1821
  exports.injectKindIntoObjectSchema = injectKindIntoObjectSchema;
@@ -1675,6 +1824,9 @@ exports.kindSchemaFromJsonSchema = kindSchemaFromJsonSchema;
1675
1824
  exports.kindSchemaToJsonSchema = kindSchemaToJsonSchema;
1676
1825
  exports.normalizeAiSchemaInput = normalizeAiSchemaInput;
1677
1826
  exports.runSchemaConversion = runSchemaConversion;
1827
+ exports.stripControlKeys = stripControlKeys;
1678
1828
  exports.validateBlockSchemaSavePlan = validateBlockSchemaSavePlan;
1829
+ exports.withControlKeyFields = withControlKeyFields;
1830
+ exports.withControlKeys = withControlKeys;
1679
1831
  //# sourceMappingURL=convert.cjs.map
1680
1832
  //# sourceMappingURL=convert.cjs.map