datagrok-tools 6.5.8 → 6.5.9

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,9 @@
1
1
  # Datagrok-tools changelog
2
2
 
3
+ ## 6.5.9 (2026-09-11)
4
+
5
+ * `grok s push/migrate` — placement no longer claims an entity the walk refused. Containment is exclusive, so asserting a project's relation to a platform entity takes it away from whatever holds it on the target: migrating a dashboard built on demo data moved `System:DemoFiles` into the migrated space, and every reference to it by name broke stand-wide until its `System` row was restored by hand. The guard covered a space's own `Files` connection but not `System:` connections, personal `Home` shares, package projects or built-in groups; it now defers to the same `untransferableReason` the walk uses.
6
+
3
7
  ## 6.5.8 (2026-09-10)
4
8
 
5
9
  * `grok s` — correctness pass from the CLI audit: every server failure now exits 1 with one line on stderr (a 200 carrying an `ApiError` — missing entity, duplicate login or group name, unknown function — used to print as data with exit 0); `--limit`/`--offset` are honoured for users, groups, connections and functions (their public routes ignore paging, so `list` and the new `count` verb go through the internal routers); `files list` works (the public files route only downloads; listing goes through the connection's file route) and prints `path, kind, size`; `tables list|get|delete` no longer throw, and `tables download|get|delete` accept the bare table name, the full `Project:Table` name or the id; `describe <entity|type>` works (registry record plus the fields of a live sample; it called a nonexistent endpoint before); positional `functions run 'F(1, 2)'` maps the values onto the function's inputs instead of silently sending `{"0": 1}` (which ran the function with nulls); `raw` takes API-relative paths (a leading `/api` is accepted), sends a body from `--json <file>` or `--data '<json>'`, and fails on non-2xx — so it, and `healthcheck`, now work against a bare-Datlas `--host` too; `shares list` accepts a name and shows the grants inherited through project links; `groups` name resolution prefers an exact match (`admin` no longer collides with `Administrators`) and `--user` works on `list-members`/`list-memberships`; `connections delete` of an unknown id fails instead of reporting success; a bad `--host` URL or alias reports the reason without the help dump. `users delete` refuses with a pointer at `users block`: the platform has no user deletion, and removing the entity record leaves the login unusable. `functions delete` covers scripts and queries.
@@ -595,11 +595,12 @@ async function pushRelations(dapi, effective, planned, rows, progress = () => {}
595
595
  let added = 0;
596
596
  for (const rel of json.relations) {
597
597
  if (linked.has(rel.entity.id)) continue;
598
- // The target stamps its own Files connection onto a space; re-attaching the source's
599
- // would leave the space with two of them.
598
+ // Placement is exclusive, so claiming an entity the walk refused takes it away from
599
+ // whatever holds it on the target: a space's own Files connection, or `System:DemoFiles`,
600
+ // which moved into a migrated space and broke every reference to it by name.
600
601
  if (!landed.has(rel.entity.id)) {
601
602
  const existing = await (0, _walker.findEntity)(dapi, rel.entity.id);
602
- if (!existing || existing.parameters?.isProject === true) continue;
603
+ if (!existing || (0, _registry.untransferableReason)(existing['#type'], existing)) continue;
603
604
  }
604
605
  wanted.push(contains(rel.entity.id) ? rel : {
605
606
  ...rel,
@@ -522,11 +522,12 @@ async function pushRelations(dapi: NodeDapi, effective: Map<string, BundleEntity
522
522
  let added = 0;
523
523
  for (const rel of json.relations) {
524
524
  if (linked.has(rel.entity.id)) continue;
525
- // The target stamps its own Files connection onto a space; re-attaching the source's
526
- // would leave the space with two of them.
525
+ // Placement is exclusive, so claiming an entity the walk refused takes it away from
526
+ // whatever holds it on the target: a space's own Files connection, or `System:DemoFiles`,
527
+ // which moved into a migrated space and broke every reference to it by name.
527
528
  if (!landed.has(rel.entity.id)) {
528
529
  const existing = await findEntity(dapi, rel.entity.id);
529
- if (!existing || existing.parameters?.isProject === true) continue;
530
+ if (!existing || untransferableReason(existing['#type'], existing)) continue;
530
531
  }
531
532
  wanted.push(contains(rel.entity.id) ? rel : {...rel, isLink: true});
532
533
  linked.add(rel.entity.id);
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/datagrok-ai/public.git"
6
6
  },
7
- "version": "6.5.8",
7
+ "version": "6.5.9",
8
8
  "description": "Utility to upload and publish packages to Datagrok",
9
9
  "homepage": "https://github.com/datagrok-ai/public/tree/master/tools#readme",
10
10
  "dependencies": {