@eide/foir-cli 0.29.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 +70 -76
  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;
@@ -1639,16 +1646,11 @@ function createRecordsMethods(client) {
1639
1646
  return { count: resp.count, ids: resp.ids };
1640
1647
  },
1641
1648
  // ── Versioning ────────────────────────────────────────────
1642
- async createVersion(parentId, data, changeDescription) {
1643
- const resp = await client.createVersion(
1644
- create4(CreateVersionRequestSchema, {
1645
- parentId,
1646
- data: data ? sanitizeData(data) : void 0,
1647
- changeDescription
1648
- })
1649
- );
1650
- return resp.version ?? null;
1651
- },
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.
1652
1654
  async publishVersion(versionId) {
1653
1655
  const resp = await client.publishVersion(
1654
1656
  create4(PublishVersionRequestSchema, { versionId })
@@ -1680,20 +1682,6 @@ function createRecordsMethods(client) {
1680
1682
  total: resp.total
1681
1683
  };
1682
1684
  },
1683
- async saveContent(params) {
1684
- const resp = await client.saveContent(
1685
- create4(SaveContentRequestSchema, {
1686
- recordId: params.recordId,
1687
- data: sanitizeData(params.data),
1688
- variantKey: params.variantKey,
1689
- changeDescription: params.changeDescription
1690
- })
1691
- );
1692
- return {
1693
- record: resp.record ?? null,
1694
- version: resp.version ?? null
1695
- };
1696
- },
1697
1685
  // ── Variants ──────────────────────────────────────────────
1698
1686
  async createVariant(recordId, variantKey, data) {
1699
1687
  const resp = await client.createVariant(
@@ -3844,31 +3832,38 @@ function isUUID(value) {
3844
3832
  ) || /^[a-z][a-z0-9]{23,31}$/.test(value);
3845
3833
  }
3846
3834
  function parseFilters(filterStr) {
3847
- if (!filterStr) return [];
3848
- return filterStr.split(",").map((part) => {
3835
+ if (!filterStr) return {};
3836
+ const where = {};
3837
+ for (const part of filterStr.split(",")) {
3849
3838
  const trimmed = part.trim();
3850
- for (const [op, gqlOp] of [
3851
- ["!=", "NE"],
3852
- [">=", "GTE"],
3853
- ["<=", "LTE"],
3854
- [">", "GT"],
3855
- ["<", "LT"],
3856
- ["~", "LIKE"],
3857
- ["=", "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"]
3858
3848
  ]) {
3859
3849
  const idx = trimmed.indexOf(op);
3860
3850
  if (idx > 0) {
3861
3851
  const field = trimmed.slice(0, idx);
3862
- const rawValue = trimmed.slice(idx + op.length);
3863
- return {
3864
- field,
3865
- operator: gqlOp,
3866
- value: parseFilterValue(rawValue)
3867
- };
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;
3868
3860
  }
3869
3861
  }
3870
- throw new Error(`Invalid filter expression: "${trimmed}"`);
3871
- });
3862
+ if (!matched) {
3863
+ throw new Error(`Invalid filter expression: "${trimmed}"`);
3864
+ }
3865
+ }
3866
+ return where;
3872
3867
  }
3873
3868
  function parseFilterValue(raw) {
3874
3869
  if (raw === "true") return true;
@@ -6719,19 +6714,19 @@ import { toJson as toJson3 } from "@bufbuild/protobuf";
6719
6714
  import { RecordSchema } from "@eide/foir-proto-ts/records/v1/records_pb";
6720
6715
  function registerRecordsCommands(program2, globalOpts) {
6721
6716
  const records = program2.command("records").description("Manage records");
6722
- 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(
6723
6718
  withErrorHandler(
6724
6719
  globalOpts,
6725
6720
  async (modelKey, cmdOpts) => {
6726
6721
  const opts = globalOpts();
6727
6722
  const client = await createPlatformClient(opts);
6728
- const params = {
6723
+ const where = cmdOpts.filter ? parseFilters(cmdOpts.filter) : void 0;
6724
+ const result = await client.records.listRecords({
6729
6725
  modelKey,
6730
- limit: parseInt(cmdOpts.limit ?? "20", 10),
6731
- offset: parseInt(cmdOpts.offset ?? "0", 10)
6732
- };
6733
- if (cmdOpts.filter) params.filters = parseFilters(cmdOpts.filter);
6734
- const result = await client.records.listRecords(params);
6726
+ first: parseInt(cmdOpts.first ?? "20", 10),
6727
+ after: cmdOpts.after || void 0,
6728
+ where
6729
+ });
6735
6730
  formatListProto(RecordSchema, result.items, opts, {
6736
6731
  columns: [
6737
6732
  { key: "id", header: "ID", width: 28 },
@@ -6815,21 +6810,20 @@ function registerRecordsCommands(program2, globalOpts) {
6815
6810
  const opts = globalOpts();
6816
6811
  const client = await createPlatformClient(opts);
6817
6812
  const inputData = await parseInputData(cmdOpts);
6818
- const result = await client.records.saveContent({
6819
- recordId: id,
6820
- data: inputData,
6813
+ const result = await client.records.updateRecord({
6814
+ id,
6815
+ replaceData: inputData,
6821
6816
  variantKey: cmdOpts.variant,
6822
6817
  changeDescription: cmdOpts.message
6823
6818
  });
6824
6819
  formatOutput(
6825
6820
  {
6826
- record: result.record ? toJson3(RecordSchema, result.record) : null,
6827
- version: result.version ? toJson3(RecordSchema, result.version) : null
6821
+ record: result ? toJson3(RecordSchema, result) : null
6828
6822
  },
6829
6823
  opts
6830
6824
  );
6831
6825
  if (!(opts.json || opts.jsonl || opts.quiet)) {
6832
- success(`Saved record ${id} \u2192 version ${result.version?.id}`);
6826
+ success(`Saved record ${id}`);
6833
6827
  }
6834
6828
  }
6835
6829
  )
@@ -6949,14 +6943,14 @@ function registerRecordsCommands(program2, globalOpts) {
6949
6943
  const opts = globalOpts();
6950
6944
  const client = await createPlatformClient(opts);
6951
6945
  const inputData = await parseInputData(cmdOpts);
6952
- const version2 = await client.records.createVersion(
6953
- parentId,
6954
- inputData,
6955
- cmdOpts.message
6956
- );
6957
- 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);
6958
6952
  if (!(opts.json || opts.jsonl || opts.quiet)) {
6959
- success(`Created version ${version2?.id}`);
6953
+ success(`Created version on ${parentId}`);
6960
6954
  }
6961
6955
  }
6962
6956
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eide/foir-cli",
3
- "version": "0.29.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",