@eide/foir-cli 0.28.0 → 0.30.1

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.
Files changed (2) hide show
  1. package/dist/cli.js +73 -78
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -1471,14 +1471,11 @@ import {
1471
1471
  DuplicateRecordsBulkRequestSchema,
1472
1472
  BatchRecordOperationsRequestSchema,
1473
1473
  BatchOperationSchema,
1474
- RecordFilterSchema,
1475
1474
  BulkUpdateRecordsRequestSchema,
1476
- CreateVersionRequestSchema,
1477
1475
  PublishVersionRequestSchema,
1478
1476
  UnpublishRecordRequestSchema,
1479
1477
  RevertToVersionRequestSchema,
1480
1478
  ListRecordVersionsRequestSchema,
1481
- SaveContentRequestSchema,
1482
1479
  CreateVariantRequestSchema,
1483
1480
  UpdateVariantRequestSchema,
1484
1481
  DeleteVariantRequestSchema,
@@ -1560,32 +1557,42 @@ function createRecordsMethods(client) {
1560
1557
  const resp = await client.listRecords(
1561
1558
  create4(ListRecordsRequestSchema, {
1562
1559
  modelKey: params.modelKey,
1563
- limit: params.limit ?? 50,
1564
- offset: params.offset ?? 0,
1565
1560
  customerId: params.customerId,
1566
1561
  search: params.search,
1567
1562
  // CLI is admin-equivalent and must see drafts; without preview the
1568
1563
  // platform now hides unpublished records on publishable models.
1569
1564
  preview: true,
1570
- filters: params.filters?.map(
1571
- (f) => create4(RecordFilterSchema, {
1572
- field: f.field,
1573
- operator: f.operator
1574
- })
1575
- )
1565
+ where: params.where ? sanitizeData(params.where) : void 0,
1566
+ first: params.first,
1567
+ after: params.after,
1568
+ last: params.last,
1569
+ before: params.before
1576
1570
  })
1577
1571
  );
1572
+ const pi = resp.pageInfo;
1578
1573
  return {
1579
1574
  items: resp.records ?? [],
1580
- total: resp.total
1575
+ total: resp.total,
1576
+ hasNextPage: pi?.hasNextPage ?? false,
1577
+ hasPreviousPage: pi?.hasPreviousPage ?? false,
1578
+ startCursor: pi?.startCursor ?? "",
1579
+ endCursor: pi?.endCursor ?? ""
1581
1580
  };
1582
1581
  },
1583
1582
  async updateRecord(params) {
1583
+ if (params.update === void 0 && params.replaceData === void 0 || params.update !== void 0 && params.replaceData !== void 0) {
1584
+ throw new Error(
1585
+ "updateRecord: exactly one of `update` or `replaceData` is required"
1586
+ );
1587
+ }
1584
1588
  const resp = await client.updateRecord(
1585
1589
  create4(UpdateRecordRequestSchema, {
1586
1590
  id: params.id,
1587
- data: sanitizeData(params.data),
1588
- naturalKey: params.naturalKey
1591
+ update: params.update ? sanitizeData(params.update) : void 0,
1592
+ replaceData: params.replaceData ? sanitizeData(params.replaceData) : void 0,
1593
+ naturalKey: params.naturalKey,
1594
+ variantKey: params.variantKey,
1595
+ changeDescription: params.changeDescription
1589
1596
  })
1590
1597
  );
1591
1598
  return resp.record ?? null;
@@ -1632,22 +1639,18 @@ function createRecordsMethods(client) {
1632
1639
  const resp = await client.bulkUpdateRecords(
1633
1640
  create4(BulkUpdateRecordsRequestSchema, {
1634
1641
  modelKey: params.modelKey,
1635
- data: sanitizeData(params.data)
1642
+ where: params.where ? sanitizeData(params.where) : void 0,
1643
+ update: sanitizeData(params.update)
1636
1644
  })
1637
1645
  );
1638
- return { count: resp.count };
1646
+ return { count: resp.count, ids: resp.ids };
1639
1647
  },
1640
1648
  // ── Versioning ────────────────────────────────────────────
1641
- async createVersion(parentId, data, changeDescription) {
1642
- const resp = await client.createVersion(
1643
- create4(CreateVersionRequestSchema, {
1644
- parentId,
1645
- data: data ? sanitizeData(data) : void 0,
1646
- changeDescription
1647
- })
1648
- );
1649
- return resp.version ?? null;
1650
- },
1649
+ //
1650
+ // "Save the whole content blob as a new version" flows go through
1651
+ // updateRecord with replaceData (+ optional variantKey /
1652
+ // changeDescription) — that one RPC subsumes the prior
1653
+ // createVersion + saveContent surface.
1651
1654
  async publishVersion(versionId) {
1652
1655
  const resp = await client.publishVersion(
1653
1656
  create4(PublishVersionRequestSchema, { versionId })
@@ -1679,20 +1682,6 @@ function createRecordsMethods(client) {
1679
1682
  total: resp.total
1680
1683
  };
1681
1684
  },
1682
- async saveContent(params) {
1683
- const resp = await client.saveContent(
1684
- create4(SaveContentRequestSchema, {
1685
- recordId: params.recordId,
1686
- data: sanitizeData(params.data),
1687
- variantKey: params.variantKey,
1688
- changeDescription: params.changeDescription
1689
- })
1690
- );
1691
- return {
1692
- record: resp.record ?? null,
1693
- version: resp.version ?? null
1694
- };
1695
- },
1696
1685
  // ── Variants ──────────────────────────────────────────────
1697
1686
  async createVariant(recordId, variantKey, data) {
1698
1687
  const resp = await client.createVariant(
@@ -3843,31 +3832,38 @@ function isUUID(value) {
3843
3832
  ) || /^[a-z][a-z0-9]{23,31}$/.test(value);
3844
3833
  }
3845
3834
  function parseFilters(filterStr) {
3846
- if (!filterStr) return [];
3847
- return filterStr.split(",").map((part) => {
3835
+ if (!filterStr) return {};
3836
+ const where = {};
3837
+ for (const part of filterStr.split(",")) {
3848
3838
  const trimmed = part.trim();
3849
- for (const [op, gqlOp] of [
3850
- ["!=", "NE"],
3851
- [">=", "GTE"],
3852
- ["<=", "LTE"],
3853
- [">", "GT"],
3854
- ["<", "LT"],
3855
- ["~", "LIKE"],
3856
- ["=", "EQ"]
3839
+ let matched = false;
3840
+ for (const [op, whereOp] of [
3841
+ ["!=", "ne"],
3842
+ [">=", "gte"],
3843
+ ["<=", "lte"],
3844
+ [">", "gt"],
3845
+ ["<", "lt"],
3846
+ ["~", "contains"],
3847
+ ["=", "eq"]
3857
3848
  ]) {
3858
3849
  const idx = trimmed.indexOf(op);
3859
3850
  if (idx > 0) {
3860
3851
  const field = trimmed.slice(0, idx);
3861
- const rawValue = trimmed.slice(idx + op.length);
3862
- return {
3863
- field,
3864
- operator: gqlOp,
3865
- value: parseFilterValue(rawValue)
3866
- };
3852
+ let rawValue = trimmed.slice(idx + op.length);
3853
+ if (whereOp === "contains") {
3854
+ rawValue = rawValue.replace(/^%/, "").replace(/%$/, "");
3855
+ }
3856
+ if (!where[field]) where[field] = {};
3857
+ where[field][whereOp] = parseFilterValue(rawValue);
3858
+ matched = true;
3859
+ break;
3867
3860
  }
3868
3861
  }
3869
- throw new Error(`Invalid filter expression: "${trimmed}"`);
3870
- });
3862
+ if (!matched) {
3863
+ throw new Error(`Invalid filter expression: "${trimmed}"`);
3864
+ }
3865
+ }
3866
+ return where;
3871
3867
  }
3872
3868
  function parseFilterValue(raw) {
3873
3869
  if (raw === "true") return true;
@@ -6718,19 +6714,19 @@ import { toJson as toJson3 } from "@bufbuild/protobuf";
6718
6714
  import { RecordSchema } from "@eide/foir-proto-ts/records/v1/records_pb";
6719
6715
  function registerRecordsCommands(program2, globalOpts) {
6720
6716
  const records = program2.command("records").description("Manage records");
6721
- records.command("list <modelKey>").description("List records for a model").option("--filter <expr>", "Filter expression (e.g. status=active)").option("--limit <n>", "Max results", "20").option("--offset <n>", "Skip results", "0").action(
6717
+ records.command("list <modelKey>").description("List records for a model").option("--filter <expr>", "Filter expression (e.g. status=active)").option("--first <n>", "Page size", "20").option("--after <cursor>", "Cursor for next page (from prior pageInfo)").action(
6722
6718
  withErrorHandler(
6723
6719
  globalOpts,
6724
6720
  async (modelKey, cmdOpts) => {
6725
6721
  const opts = globalOpts();
6726
6722
  const client = await createPlatformClient(opts);
6727
- const params = {
6723
+ const where = cmdOpts.filter ? parseFilters(cmdOpts.filter) : void 0;
6724
+ const result = await client.records.listRecords({
6728
6725
  modelKey,
6729
- limit: parseInt(cmdOpts.limit ?? "20", 10),
6730
- offset: parseInt(cmdOpts.offset ?? "0", 10)
6731
- };
6732
- if (cmdOpts.filter) params.filters = parseFilters(cmdOpts.filter);
6733
- const result = await client.records.listRecords(params);
6726
+ first: parseInt(cmdOpts.first ?? "20", 10),
6727
+ after: cmdOpts.after || void 0,
6728
+ where
6729
+ });
6734
6730
  formatListProto(RecordSchema, result.items, opts, {
6735
6731
  columns: [
6736
6732
  { key: "id", header: "ID", width: 28 },
@@ -6814,21 +6810,20 @@ function registerRecordsCommands(program2, globalOpts) {
6814
6810
  const opts = globalOpts();
6815
6811
  const client = await createPlatformClient(opts);
6816
6812
  const inputData = await parseInputData(cmdOpts);
6817
- const result = await client.records.saveContent({
6818
- recordId: id,
6819
- data: inputData,
6813
+ const result = await client.records.updateRecord({
6814
+ id,
6815
+ replaceData: inputData,
6820
6816
  variantKey: cmdOpts.variant,
6821
6817
  changeDescription: cmdOpts.message
6822
6818
  });
6823
6819
  formatOutput(
6824
6820
  {
6825
- record: result.record ? toJson3(RecordSchema, result.record) : null,
6826
- version: result.version ? toJson3(RecordSchema, result.version) : null
6821
+ record: result ? toJson3(RecordSchema, result) : null
6827
6822
  },
6828
6823
  opts
6829
6824
  );
6830
6825
  if (!(opts.json || opts.jsonl || opts.quiet)) {
6831
- success(`Saved record ${id} \u2192 version ${result.version?.id}`);
6826
+ success(`Saved record ${id}`);
6832
6827
  }
6833
6828
  }
6834
6829
  )
@@ -6948,14 +6943,14 @@ function registerRecordsCommands(program2, globalOpts) {
6948
6943
  const opts = globalOpts();
6949
6944
  const client = await createPlatformClient(opts);
6950
6945
  const inputData = await parseInputData(cmdOpts);
6951
- const version2 = await client.records.createVersion(
6952
- parentId,
6953
- inputData,
6954
- cmdOpts.message
6955
- );
6956
- formatOutputProto(RecordSchema, version2, opts);
6946
+ const record = await client.records.updateRecord({
6947
+ id: parentId,
6948
+ replaceData: inputData,
6949
+ changeDescription: cmdOpts.message
6950
+ });
6951
+ formatOutputProto(RecordSchema, record, opts);
6957
6952
  if (!(opts.json || opts.jsonl || opts.quiet)) {
6958
- success(`Created version ${version2?.id}`);
6953
+ success(`Created version on ${parentId}`);
6959
6954
  }
6960
6955
  }
6961
6956
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eide/foir-cli",
3
- "version": "0.28.0",
3
+ "version": "0.30.1",
4
4
  "description": "Universal platform CLI for Foir platform",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -50,7 +50,7 @@
50
50
  "@bufbuild/protovalidate": "^1.1.1",
51
51
  "@connectrpc/connect": "^2.0.0",
52
52
  "@connectrpc/connect-node": "^2.0.0",
53
- "@eide/foir-proto-ts": "^0.71.0",
53
+ "@eide/foir-proto-ts": "^0.77.0",
54
54
  "chalk": "^5.3.0",
55
55
  "commander": "^12.1.0",
56
56
  "dotenv": "^16.4.5",