@narrative.io/data-collaboration-sdk-ts 3.0.1 → 3.1.0

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.
@@ -32,14 +32,86 @@ export function parseExplain(n) {
32
32
  return nqlOrFail(n);
33
33
  }
34
34
  }
35
+ function isRecord(value) {
36
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37
+ }
38
+ function walkNodes(value, visit) {
39
+ if (Array.isArray(value)) {
40
+ for (const item of value)
41
+ walkNodes(item, visit);
42
+ return;
43
+ }
44
+ if (isRecord(value)) {
45
+ visit(value);
46
+ for (const key of Object.keys(value))
47
+ walkNodes(value[key], visit);
48
+ }
49
+ }
50
+ // The server qualifies first-party (`company_data`) refs by dataset NAME when a
51
+ // query was written by name (e.g. `company_data.my_dataset`), echoing the name in
52
+ // the `table` field and carrying the numeric dataset id only in a table node's
53
+ // `metadata.id`. `parseTable`/`parseColumnRef` bind a dataset node only when
54
+ // `table` is the numeric id, so we first rewrite name-qualified first-party refs
55
+ // back to their id: build a name/alias -> id map from the FROM tables' metadata,
56
+ // then rewrite both the table refs and the column refs that point at them. Id-form
57
+ // queries are unaffected, and non-`company_data` schemas (e.g. third-party access
58
+ // rules `<slug>.<name>`) are left untouched.
59
+ function resolveFirstPartyDatasetId(node) {
60
+ const table = node.table;
61
+ if (typeof table === "string" && /^\d+$/.test(table)) {
62
+ return Number.parseInt(table, 10);
63
+ }
64
+ const metadata = node.metadata;
65
+ if (isRecord(metadata)) {
66
+ const id = metadata.id;
67
+ if (typeof id === "number")
68
+ return id;
69
+ if (typeof id === "string" && /^\d+$/.test(id)) {
70
+ return Number.parseInt(id, 10);
71
+ }
72
+ }
73
+ return undefined;
74
+ }
75
+ function normalizeFirstPartyRefs(n) {
76
+ const clone = JSON.parse(JSON.stringify(n));
77
+ const idByRef = new Map();
78
+ // Pass 1: first-party FROM tables — record name/alias -> id, rewrite to id.
79
+ walkNodes(clone, (node) => {
80
+ if (node.type !== "table" || node.schema !== "company_data")
81
+ return;
82
+ const id = resolveFirstPartyDatasetId(node);
83
+ if (id === undefined)
84
+ return;
85
+ if (typeof node.table === "string")
86
+ idByRef.set(node.table, id);
87
+ if (typeof node.as === "string")
88
+ idByRef.set(node.as, id);
89
+ idByRef.set(String(id), id);
90
+ node.table = String(id);
91
+ });
92
+ if (idByRef.size === 0)
93
+ return clone;
94
+ // Pass 2: first-party column refs still qualified by name -> rewrite to id.
95
+ walkNodes(clone, (node) => {
96
+ if (node.type !== "column" || node.schema !== "company_data")
97
+ return;
98
+ if (typeof node.table !== "string" || /^\d+$/.test(node.table))
99
+ return;
100
+ const id = idByRef.get(node.table);
101
+ if (id !== undefined)
102
+ node.table = String(id);
103
+ });
104
+ return clone;
105
+ }
35
106
  export function parseSelect(n) {
107
+ const normalized = normalizeFirstPartyRefs(n);
36
108
  const select = {
37
109
  type: "select",
38
- budget: n.budget,
39
- columns: n.columns.map((col) => parseOutput(col)),
40
- deduplication: parseDeduplication(n),
41
- from: n.from !== null ? parseFrom(n.from) : [],
42
- where: n.where !== null ? parseWhere(n.where) : null,
110
+ budget: normalized.budget,
111
+ columns: normalized.columns.map((col) => parseOutput(col)),
112
+ deduplication: parseDeduplication(normalized),
113
+ from: normalized.from !== null ? parseFrom(normalized.from) : [],
114
+ where: normalized.where !== null ? parseWhere(normalized.where) : null,
43
115
  };
44
116
  return select;
45
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narrative.io/data-collaboration-sdk-ts",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "main": "build/index.js",
5
5
  "repository": "github:narrative-io/data-collaboration-sdk-ts",
6
6
  "source": "src/index.ts",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "zod": "4.4.3",
44
- "bignumber.js": "11.1.2"
44
+ "bignumber.js": "11.1.3"
45
45
  },
46
46
  "overrides": {
47
47
  "semver@<7.5.2": "7.5.2"