@sixb/pg 0.1.7 → 0.1.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/dist/agents/rows.d.ts +0 -1
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7596 -6416
- package/dist/index.js.map +25 -19
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/index.d.ts +2 -0
- package/dist/objects/index.d.ts.map +1 -0
- package/dist/{pg-object-query-compiler.d.ts → objects/query-compiler.d.ts} +25 -4
- package/dist/objects/query-compiler.d.ts.map +1 -0
- package/dist/objects/read-scope.d.ts +17 -0
- package/dist/objects/read-scope.d.ts.map +1 -0
- package/dist/objects/reader.d.ts +50 -0
- package/dist/objects/reader.d.ts.map +1 -0
- package/dist/objects/rows.d.ts +47 -0
- package/dist/objects/rows.d.ts.map +1 -0
- package/dist/objects/selected-reader.d.ts +8 -0
- package/dist/objects/selected-reader.d.ts.map +1 -0
- package/dist/{pg-object-storage.d.ts → objects/storage.d.ts} +12 -20
- package/dist/objects/storage.d.ts.map +1 -0
- package/dist/pg-action-run-storage.d.ts.map +1 -1
- package/dist/pg-ai-cost-storage.d.ts.map +1 -1
- package/dist/pg-ai-usage-storage.d.ts.map +1 -1
- package/dist/pg-execution-storage.d.ts +3 -2
- package/dist/pg-execution-storage.d.ts.map +1 -1
- package/dist/pg-pipeline-run-storage.d.ts.map +1 -1
- package/dist/pg-sync-run-storage.d.ts.map +1 -1
- package/dist/pg-workflow-run-storage.d.ts.map +1 -1
- package/dist/share-grant-storage.d.ts +11 -0
- package/dist/share-grant-storage.d.ts.map +1 -0
- package/dist/share-session-storage.d.ts +11 -0
- package/dist/share-session-storage.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +2 -0
- package/dist/storage-errors.d.ts.map +1 -1
- package/dist/transactions.d.ts +9 -2
- package/dist/transactions.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/agents/rows.ts +0 -5
- package/src/agents/runs.ts +1 -6
- package/src/ai-cost-groups.ts +3 -0
- package/src/index.ts +20 -5
- package/src/migrations/035-share-grants.sql +57 -0
- package/src/migrations/036-share-sessions.sql +173 -0
- package/src/migrations/037-execution-requester-groups.sql +21 -0
- package/src/migrations.ts +9 -0
- package/src/objects/index.ts +1 -0
- package/src/{pg-object-query-compiler.ts → objects/query-compiler.ts} +185 -100
- package/src/objects/read-scope.ts +324 -0
- package/src/objects/reader.ts +604 -0
- package/src/objects/rows.ts +146 -0
- package/src/objects/selected-reader.ts +118 -0
- package/src/objects/storage.ts +305 -0
- package/src/pg-action-run-storage.ts +6 -7
- package/src/pg-ai-cost-storage.ts +11 -2
- package/src/pg-ai-usage-storage.ts +1 -2
- package/src/pg-execution-storage.ts +27 -6
- package/src/pg-pipeline-run-storage.ts +2 -5
- package/src/pg-sync-run-storage.ts +2 -5
- package/src/pg-workflow-run-storage.ts +0 -5
- package/src/share-grant-storage.ts +236 -0
- package/src/share-session-storage.ts +127 -0
- package/src/storage-errors.ts +6 -0
- package/src/transactions.ts +46 -5
- package/dist/pg-object-query-compiler.d.ts.map +0 -1
- package/dist/pg-object-storage.d.ts.map +0 -1
- package/src/pg-object-storage.ts +0 -734
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import type { CompiledSelectedObjectReadScope } from "@sixb/core/storage"
|
|
2
|
+
import {
|
|
3
|
+
type CompiledPgObjectQuery,
|
|
4
|
+
compilePgObjectStatement,
|
|
5
|
+
type PgObjectQuerySource,
|
|
6
|
+
} from "./query-compiler"
|
|
7
|
+
|
|
8
|
+
export interface PgSelectedObjectReadSource extends PgObjectQuerySource {
|
|
9
|
+
readonly objectPropertyPermissionsTable: string
|
|
10
|
+
readonly traversalProbe: {
|
|
11
|
+
readonly sql: string
|
|
12
|
+
readonly args: readonly unknown[]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Prepare one immutable selected scope as live, path-sensitive PostgreSQL relations.
|
|
18
|
+
*
|
|
19
|
+
* The complete compiled scope is serialized once. Every statement receives that one JSONB
|
|
20
|
+
* document and the bound project id, keeping the parameter count constant as selections grow.
|
|
21
|
+
*/
|
|
22
|
+
export function compilePgSelectedObjectReadSource(
|
|
23
|
+
projectId: string,
|
|
24
|
+
scope: CompiledSelectedObjectReadScope,
|
|
25
|
+
maxTraversalFacts: number
|
|
26
|
+
): PgSelectedObjectReadSource {
|
|
27
|
+
const scopeJson = JSON.stringify({
|
|
28
|
+
roots: scope.roots,
|
|
29
|
+
objects: scope.objects,
|
|
30
|
+
steps: scope.steps,
|
|
31
|
+
})
|
|
32
|
+
const compiled = compileSelectedReadScopeCte(scopeJson, projectId)
|
|
33
|
+
const wrapStatement = (sql: string, args: readonly unknown[] = []) => ({
|
|
34
|
+
sql: `${compiled.sql}\n${sql}`,
|
|
35
|
+
args: [...compiled.args, ...args],
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const source: PgSelectedObjectReadSource = {
|
|
39
|
+
objectsTable: "_sixb_scope_objects",
|
|
40
|
+
linksTable: "_sixb_scope_links",
|
|
41
|
+
objectPropertyPermissionsTable: "_sixb_scope_object_permissions",
|
|
42
|
+
wrapStatement,
|
|
43
|
+
wrapQuery: (query: CompiledPgObjectQuery): CompiledPgObjectQuery => ({
|
|
44
|
+
...query,
|
|
45
|
+
...wrapStatement(query.sql, query.args),
|
|
46
|
+
totalSql: `${compiled.sql}\n${query.totalSql}`,
|
|
47
|
+
totalArgs: [...compiled.args, ...query.totalArgs],
|
|
48
|
+
...(query.hasMoreProbe
|
|
49
|
+
? {
|
|
50
|
+
hasMoreProbe: {
|
|
51
|
+
...query.hasMoreProbe,
|
|
52
|
+
...wrapStatement(query.hasMoreProbe.sql, query.hasMoreProbe.args),
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
: {}),
|
|
56
|
+
}),
|
|
57
|
+
traversalProbe: { sql: "", args: [] },
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const traversalProbe = compilePgObjectStatement(
|
|
61
|
+
`
|
|
62
|
+
SELECT COUNT(*)::bigint AS total
|
|
63
|
+
FROM (
|
|
64
|
+
SELECT 1 AS traversal_fact
|
|
65
|
+
FROM _sixb_scope_root_facts
|
|
66
|
+
|
|
67
|
+
UNION ALL
|
|
68
|
+
|
|
69
|
+
SELECT 1 AS traversal_fact
|
|
70
|
+
FROM _sixb_scope_reached_links
|
|
71
|
+
|
|
72
|
+
LIMIT ?
|
|
73
|
+
) AS bounded_traversal_facts
|
|
74
|
+
`,
|
|
75
|
+
[BigInt(maxTraversalFacts) + 1n],
|
|
76
|
+
source
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return Object.freeze({ ...source, traversalProbe })
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface CompiledReadScopeCte {
|
|
83
|
+
readonly sql: string
|
|
84
|
+
readonly args: readonly unknown[]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function compileSelectedReadScopeCte(scopeJson: string, projectId: string): CompiledReadScopeCte {
|
|
88
|
+
return {
|
|
89
|
+
sql: `
|
|
90
|
+
WITH RECURSIVE
|
|
91
|
+
_sixb_scope_document(scope) AS (
|
|
92
|
+
SELECT ?::text::jsonb
|
|
93
|
+
),
|
|
94
|
+
_sixb_scope_roots(root_id, node_id, object_type_id, primary_id) AS (
|
|
95
|
+
SELECT
|
|
96
|
+
(root.ordinality - 1)::integer,
|
|
97
|
+
(root.value ->> 'nodeId')::integer,
|
|
98
|
+
root.value ->> 'objectTypeId',
|
|
99
|
+
root.value ->> 'primaryId'
|
|
100
|
+
FROM _sixb_scope_document AS document
|
|
101
|
+
CROSS JOIN LATERAL jsonb_array_elements(document.scope -> 'roots')
|
|
102
|
+
WITH ORDINALITY AS root(value, ordinality)
|
|
103
|
+
),
|
|
104
|
+
_sixb_scope_root_facts(project_id, root_id, node_id, object_type_id, primary_id) AS (
|
|
105
|
+
SELECT anchor.project_id, root.root_id, root.node_id, root.object_type_id, root.primary_id
|
|
106
|
+
FROM _sixb_scope_roots AS root
|
|
107
|
+
JOIN objects AS anchor
|
|
108
|
+
ON anchor.project_id = ?
|
|
109
|
+
AND anchor.object_type_id = root.object_type_id
|
|
110
|
+
AND anchor.primary_id = root.primary_id
|
|
111
|
+
),
|
|
112
|
+
_sixb_scope_object_selections(node_id, object_type_id, property_ids) AS (
|
|
113
|
+
SELECT
|
|
114
|
+
(selection.value ->> 'nodeId')::integer,
|
|
115
|
+
selection.value ->> 'objectTypeId',
|
|
116
|
+
selection.value -> 'propertyIds'
|
|
117
|
+
FROM _sixb_scope_document AS document
|
|
118
|
+
CROSS JOIN LATERAL jsonb_array_elements(document.scope -> 'objects') AS selection(value)
|
|
119
|
+
),
|
|
120
|
+
_sixb_scope_link_selections(
|
|
121
|
+
step_id,
|
|
122
|
+
node_id,
|
|
123
|
+
parent_node_id,
|
|
124
|
+
source_object_type_id,
|
|
125
|
+
link_id,
|
|
126
|
+
target_object_type_id,
|
|
127
|
+
property_ids
|
|
128
|
+
) AS (
|
|
129
|
+
SELECT
|
|
130
|
+
(step.ordinality - 1)::integer,
|
|
131
|
+
(step.value ->> 'nodeId')::integer,
|
|
132
|
+
(step.value ->> 'parentNodeId')::integer,
|
|
133
|
+
step.value ->> 'sourceObjectTypeId',
|
|
134
|
+
step.value ->> 'linkId',
|
|
135
|
+
step.value ->> 'targetObjectTypeId',
|
|
136
|
+
step.value -> 'propertyIds'
|
|
137
|
+
FROM _sixb_scope_document AS document
|
|
138
|
+
CROSS JOIN LATERAL jsonb_array_elements(document.scope -> 'steps')
|
|
139
|
+
WITH ORDINALITY AS step(value, ordinality)
|
|
140
|
+
),
|
|
141
|
+
_sixb_scope_reachable(project_id, node_id, object_type_id, primary_id) AS (
|
|
142
|
+
SELECT root.project_id, root.node_id, root.object_type_id, root.primary_id
|
|
143
|
+
FROM _sixb_scope_root_facts AS root
|
|
144
|
+
|
|
145
|
+
UNION
|
|
146
|
+
|
|
147
|
+
SELECT edge.project_id, selection.node_id, edge.target_type_id, edge.target_id
|
|
148
|
+
FROM _sixb_scope_reachable AS parent
|
|
149
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
150
|
+
ON selection.parent_node_id = parent.node_id
|
|
151
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
152
|
+
JOIN links AS edge
|
|
153
|
+
ON edge.project_id = parent.project_id
|
|
154
|
+
AND edge.source_type_id = parent.object_type_id
|
|
155
|
+
AND edge.source_id = parent.primary_id
|
|
156
|
+
AND edge.link_id = selection.link_id
|
|
157
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
158
|
+
JOIN objects AS target
|
|
159
|
+
ON target.project_id = edge.project_id
|
|
160
|
+
AND target.object_type_id = edge.target_type_id
|
|
161
|
+
AND target.primary_id = edge.target_id
|
|
162
|
+
),
|
|
163
|
+
_sixb_scope_object_permissions(project_id, object_type_id, primary_id, property_id) AS (
|
|
164
|
+
SELECT DISTINCT
|
|
165
|
+
reachable.project_id,
|
|
166
|
+
reachable.object_type_id,
|
|
167
|
+
reachable.primary_id,
|
|
168
|
+
selected_property.value
|
|
169
|
+
FROM _sixb_scope_reachable AS reachable
|
|
170
|
+
JOIN _sixb_scope_object_selections AS selection
|
|
171
|
+
ON selection.node_id = reachable.node_id
|
|
172
|
+
AND selection.object_type_id = reachable.object_type_id
|
|
173
|
+
CROSS JOIN LATERAL jsonb_array_elements_text(selection.property_ids)
|
|
174
|
+
AS selected_property(value)
|
|
175
|
+
),
|
|
176
|
+
_sixb_scope_object_ids(project_id, object_type_id, primary_id) AS (
|
|
177
|
+
SELECT DISTINCT project_id, object_type_id, primary_id
|
|
178
|
+
FROM _sixb_scope_reachable
|
|
179
|
+
),
|
|
180
|
+
_sixb_scope_objects AS (
|
|
181
|
+
SELECT
|
|
182
|
+
stored.project_id,
|
|
183
|
+
stored.object_type_id,
|
|
184
|
+
stored.primary_id,
|
|
185
|
+
COALESCE(
|
|
186
|
+
(
|
|
187
|
+
SELECT jsonb_object_agg(property.key, property.value)
|
|
188
|
+
FROM jsonb_each(stored.properties) AS property(key, value)
|
|
189
|
+
JOIN _sixb_scope_object_permissions AS permission
|
|
190
|
+
ON permission.project_id = stored.project_id
|
|
191
|
+
AND permission.object_type_id = stored.object_type_id
|
|
192
|
+
AND permission.primary_id = stored.primary_id
|
|
193
|
+
AND permission.property_id = property.key
|
|
194
|
+
),
|
|
195
|
+
'{}'::jsonb
|
|
196
|
+
) AS properties,
|
|
197
|
+
stored.created_at,
|
|
198
|
+
stored.updated_at,
|
|
199
|
+
stored.version,
|
|
200
|
+
stored.last_commit_id
|
|
201
|
+
FROM objects AS stored
|
|
202
|
+
JOIN _sixb_scope_object_ids AS visible
|
|
203
|
+
ON visible.project_id = stored.project_id
|
|
204
|
+
AND visible.object_type_id = stored.object_type_id
|
|
205
|
+
AND visible.primary_id = stored.primary_id
|
|
206
|
+
),
|
|
207
|
+
_sixb_scope_reached_links(
|
|
208
|
+
project_id,
|
|
209
|
+
step_id,
|
|
210
|
+
node_id,
|
|
211
|
+
parent_node_id,
|
|
212
|
+
source_type_id,
|
|
213
|
+
source_id,
|
|
214
|
+
link_id,
|
|
215
|
+
target_type_id,
|
|
216
|
+
target_id,
|
|
217
|
+
property_ids
|
|
218
|
+
) AS (
|
|
219
|
+
SELECT
|
|
220
|
+
edge.project_id,
|
|
221
|
+
selection.step_id,
|
|
222
|
+
selection.node_id,
|
|
223
|
+
selection.parent_node_id,
|
|
224
|
+
edge.source_type_id,
|
|
225
|
+
edge.source_id,
|
|
226
|
+
edge.link_id,
|
|
227
|
+
edge.target_type_id,
|
|
228
|
+
edge.target_id,
|
|
229
|
+
selection.property_ids
|
|
230
|
+
FROM _sixb_scope_reachable AS parent
|
|
231
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
232
|
+
ON selection.parent_node_id = parent.node_id
|
|
233
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
234
|
+
JOIN links AS edge
|
|
235
|
+
ON edge.project_id = parent.project_id
|
|
236
|
+
AND edge.source_type_id = parent.object_type_id
|
|
237
|
+
AND edge.source_id = parent.primary_id
|
|
238
|
+
AND edge.link_id = selection.link_id
|
|
239
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
240
|
+
JOIN objects AS target
|
|
241
|
+
ON target.project_id = edge.project_id
|
|
242
|
+
AND target.object_type_id = edge.target_type_id
|
|
243
|
+
AND target.primary_id = edge.target_id
|
|
244
|
+
),
|
|
245
|
+
_sixb_scope_link_permissions(
|
|
246
|
+
project_id,
|
|
247
|
+
source_type_id,
|
|
248
|
+
source_id,
|
|
249
|
+
link_id,
|
|
250
|
+
target_type_id,
|
|
251
|
+
target_id,
|
|
252
|
+
property_id
|
|
253
|
+
) AS (
|
|
254
|
+
SELECT DISTINCT
|
|
255
|
+
reached.project_id,
|
|
256
|
+
reached.source_type_id,
|
|
257
|
+
reached.source_id,
|
|
258
|
+
reached.link_id,
|
|
259
|
+
reached.target_type_id,
|
|
260
|
+
reached.target_id,
|
|
261
|
+
selected_property.value
|
|
262
|
+
FROM _sixb_scope_reached_links AS reached
|
|
263
|
+
CROSS JOIN LATERAL jsonb_array_elements_text(reached.property_ids)
|
|
264
|
+
AS selected_property(value)
|
|
265
|
+
),
|
|
266
|
+
_sixb_scope_link_ids(
|
|
267
|
+
project_id,
|
|
268
|
+
source_type_id,
|
|
269
|
+
source_id,
|
|
270
|
+
link_id,
|
|
271
|
+
target_type_id,
|
|
272
|
+
target_id
|
|
273
|
+
) AS (
|
|
274
|
+
SELECT DISTINCT
|
|
275
|
+
project_id,
|
|
276
|
+
source_type_id,
|
|
277
|
+
source_id,
|
|
278
|
+
link_id,
|
|
279
|
+
target_type_id,
|
|
280
|
+
target_id
|
|
281
|
+
FROM _sixb_scope_reached_links
|
|
282
|
+
),
|
|
283
|
+
_sixb_scope_links AS (
|
|
284
|
+
SELECT
|
|
285
|
+
stored.project_id,
|
|
286
|
+
stored.source_type_id,
|
|
287
|
+
stored.source_id,
|
|
288
|
+
stored.link_id,
|
|
289
|
+
stored.target_type_id,
|
|
290
|
+
stored.target_id,
|
|
291
|
+
CASE
|
|
292
|
+
WHEN stored.properties IS NULL THEN NULL
|
|
293
|
+
ELSE NULLIF(
|
|
294
|
+
(
|
|
295
|
+
SELECT jsonb_object_agg(property.key, property.value)
|
|
296
|
+
FROM jsonb_each(stored.properties) AS property(key, value)
|
|
297
|
+
JOIN _sixb_scope_link_permissions AS permission
|
|
298
|
+
ON permission.project_id = stored.project_id
|
|
299
|
+
AND permission.source_type_id = stored.source_type_id
|
|
300
|
+
AND permission.source_id = stored.source_id
|
|
301
|
+
AND permission.link_id = stored.link_id
|
|
302
|
+
AND permission.target_type_id = stored.target_type_id
|
|
303
|
+
AND permission.target_id = stored.target_id
|
|
304
|
+
AND permission.property_id = property.key
|
|
305
|
+
),
|
|
306
|
+
'{}'::jsonb
|
|
307
|
+
)
|
|
308
|
+
END AS properties,
|
|
309
|
+
stored.created_at,
|
|
310
|
+
stored.updated_at,
|
|
311
|
+
stored.last_commit_id
|
|
312
|
+
FROM links AS stored
|
|
313
|
+
JOIN _sixb_scope_link_ids AS visible
|
|
314
|
+
ON visible.project_id = stored.project_id
|
|
315
|
+
AND visible.source_type_id = stored.source_type_id
|
|
316
|
+
AND visible.source_id = stored.source_id
|
|
317
|
+
AND visible.link_id = stored.link_id
|
|
318
|
+
AND visible.target_type_id = stored.target_type_id
|
|
319
|
+
AND visible.target_id = stored.target_id
|
|
320
|
+
)
|
|
321
|
+
`,
|
|
322
|
+
args: [scopeJson, projectId],
|
|
323
|
+
}
|
|
324
|
+
}
|