@sixb/sqlite 0.0.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.
- package/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/action-run-storage.d.ts +29 -0
- package/dist/action-run-storage.d.ts.map +1 -0
- package/dist/agents/agent-storage.d.ts +25 -0
- package/dist/agents/agent-storage.d.ts.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/messages.d.ts +14 -0
- package/dist/agents/messages.d.ts.map +1 -0
- package/dist/agents/rows.d.ts +77 -0
- package/dist/agents/rows.d.ts.map +1 -0
- package/dist/agents/runs.d.ts +26 -0
- package/dist/agents/runs.d.ts.map +1 -0
- package/dist/agents/threads.d.ts +14 -0
- package/dist/agents/threads.d.ts.map +1 -0
- package/dist/auth-storage/access-tokens.d.ts +33 -0
- package/dist/auth-storage/access-tokens.d.ts.map +1 -0
- package/dist/auth-storage/auth-storage.d.ts +46 -0
- package/dist/auth-storage/auth-storage.d.ts.map +1 -0
- package/dist/auth-storage/group-memberships.d.ts +21 -0
- package/dist/auth-storage/group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/identities.d.ts +17 -0
- package/dist/auth-storage/identities.d.ts.map +1 -0
- package/dist/auth-storage/index.d.ts +3 -0
- package/dist/auth-storage/index.d.ts.map +1 -0
- package/dist/auth-storage/invitations.d.ts +28 -0
- package/dist/auth-storage/invitations.d.ts.map +1 -0
- package/dist/auth-storage/magic-links.d.ts +28 -0
- package/dist/auth-storage/magic-links.d.ts.map +1 -0
- package/dist/auth-storage/oidc-attempts.d.ts +18 -0
- package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
- package/dist/auth-storage/rows.d.ts +134 -0
- package/dist/auth-storage/rows.d.ts.map +1 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/service-accounts.d.ts +14 -0
- package/dist/auth-storage/service-accounts.d.ts.map +1 -0
- package/dist/auth-storage/sessions.d.ts +55 -0
- package/dist/auth-storage/sessions.d.ts.map +1 -0
- package/dist/auth-storage/shared.d.ts +131 -0
- package/dist/auth-storage/shared.d.ts.map +1 -0
- package/dist/auth-storage/users.d.ts +19 -0
- package/dist/auth-storage/users.d.ts.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10204 -0
- package/dist/index.js.map +54 -0
- package/dist/latest-run-query.d.ts +22 -0
- package/dist/latest-run-query.d.ts.map +1 -0
- package/dist/migrations.d.ts +18 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/object-query-compiler.d.ts +44 -0
- package/dist/object-query-compiler.d.ts.map +1 -0
- package/dist/object-storage.d.ts +93 -0
- package/dist/object-storage.d.ts.map +1 -0
- package/dist/ontology-storage/commits.d.ts +14 -0
- package/dist/ontology-storage/commits.d.ts.map +1 -0
- package/dist/ontology-storage/index.d.ts +22 -0
- package/dist/ontology-storage/index.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-session.d.ts +49 -0
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-state.d.ts +63 -0
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-writer.d.ts +15 -0
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
- package/dist/ontology-storage/materializations.d.ts +32 -0
- package/dist/ontology-storage/materializations.d.ts.map +1 -0
- package/dist/ontology-storage/outbox.d.ts +14 -0
- package/dist/ontology-storage/outbox.d.ts.map +1 -0
- package/dist/ontology-storage/shared.d.ts +91 -0
- package/dist/ontology-storage/shared.d.ts.map +1 -0
- package/dist/ontology-storage/sources.d.ts +26 -0
- package/dist/ontology-storage/sources.d.ts.map +1 -0
- package/dist/pipeline-run-storage.d.ts +26 -0
- package/dist/pipeline-run-storage.d.ts.map +1 -0
- package/dist/projection-run-storage.d.ts +32 -0
- package/dist/projection-run-storage.d.ts.map +1 -0
- package/dist/rules-storage.d.ts +33 -0
- package/dist/rules-storage.d.ts.map +1 -0
- package/dist/run-list-query.d.ts +27 -0
- package/dist/run-list-query.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +2 -0
- package/dist/storage-errors.d.ts.map +1 -0
- package/dist/sync-run-storage.d.ts +23 -0
- package/dist/sync-run-storage.d.ts.map +1 -0
- package/dist/timeseries-storage.d.ts +41 -0
- package/dist/timeseries-storage.d.ts.map +1 -0
- package/dist/transactions.d.ts +15 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/tsconfig.json +5 -0
- package/dist/validation.d.ts +5 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/webhook-delivery-storage.d.ts +27 -0
- package/dist/webhook-delivery-storage.d.ts.map +1 -0
- package/dist/webhook-run-storage.d.ts +22 -0
- package/dist/webhook-run-storage.d.ts.map +1 -0
- package/dist/workflow-intervention-storage.d.ts +26 -0
- package/dist/workflow-intervention-storage.d.ts.map +1 -0
- package/dist/workflow-run-storage.d.ts +63 -0
- package/dist/workflow-run-storage.d.ts.map +1 -0
- package/package.json +58 -0
- package/src/action-run-storage.ts +761 -0
- package/src/agents/agent-storage.ts +46 -0
- package/src/agents/index.ts +5 -0
- package/src/agents/messages.ts +162 -0
- package/src/agents/rows.ts +205 -0
- package/src/agents/runs.ts +389 -0
- package/src/agents/threads.ts +133 -0
- package/src/auth-storage/access-tokens.ts +289 -0
- package/src/auth-storage/auth-storage.ts +784 -0
- package/src/auth-storage/group-memberships.ts +52 -0
- package/src/auth-storage/identities.ts +98 -0
- package/src/auth-storage/index.ts +2 -0
- package/src/auth-storage/invitations.ts +258 -0
- package/src/auth-storage/magic-links.ts +149 -0
- package/src/auth-storage/oidc-attempts.ts +109 -0
- package/src/auth-storage/rows.ts +338 -0
- package/src/auth-storage/service-account-group-memberships.ts +161 -0
- package/src/auth-storage/service-accounts.ts +168 -0
- package/src/auth-storage/sessions.ts +230 -0
- package/src/auth-storage/shared.ts +707 -0
- package/src/auth-storage/users.ts +226 -0
- package/src/index.ts +292 -0
- package/src/latest-run-query.ts +49 -0
- package/src/migrations/001-initial-schema.sql +1068 -0
- package/src/migrations.ts +245 -0
- package/src/object-query-compiler.ts +1198 -0
- package/src/object-storage.ts +605 -0
- package/src/ontology-storage/commits.ts +127 -0
- package/src/ontology-storage/index.ts +35 -0
- package/src/ontology-storage/materialization-session.ts +393 -0
- package/src/ontology-storage/materialization-state.ts +901 -0
- package/src/ontology-storage/materialization-writer.ts +394 -0
- package/src/ontology-storage/materializations.ts +838 -0
- package/src/ontology-storage/outbox.ts +237 -0
- package/src/ontology-storage/shared.ts +269 -0
- package/src/ontology-storage/sources.ts +653 -0
- package/src/pipeline-run-storage.ts +506 -0
- package/src/projection-run-storage.ts +592 -0
- package/src/rules-storage.ts +375 -0
- package/src/run-list-query.ts +98 -0
- package/src/sql.d.ts +4 -0
- package/src/storage-errors.ts +3 -0
- package/src/sync-run-storage.ts +299 -0
- package/src/timeseries-storage.ts +212 -0
- package/src/transactions.ts +96 -0
- package/src/validation.ts +30 -0
- package/src/webhook-delivery-storage.ts +272 -0
- package/src/webhook-run-storage.ts +240 -0
- package/src/workflow-intervention-storage.ts +398 -0
- package/src/workflow-run-storage.ts +1148 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import type { Database } from "bun:sqlite"
|
|
2
|
+
import type { WorkflowIOSnapshot } from "@sixb/core/internal/workflows"
|
|
3
|
+
import type {
|
|
4
|
+
CancelWorkflowInterventionInput,
|
|
5
|
+
CreateWorkflowInterventionInput,
|
|
6
|
+
ExpireWorkflowInterventionInput,
|
|
7
|
+
ListWorkflowInterventionsInput,
|
|
8
|
+
ListWorkflowInterventionsResult,
|
|
9
|
+
SubmitWorkflowInterventionInput,
|
|
10
|
+
WorkflowInterventionActor,
|
|
11
|
+
WorkflowInterventionRecord,
|
|
12
|
+
WorkflowInterventionStorage,
|
|
13
|
+
} from "@sixb/core/storage"
|
|
14
|
+
import { WorkflowInterventionError } from "@sixb/core/storage"
|
|
15
|
+
import { installFreshSqliteSchema } from "./migrations"
|
|
16
|
+
import { isUniqueConstraintError } from "./storage-errors"
|
|
17
|
+
import {
|
|
18
|
+
closeSqliteStoreConnection,
|
|
19
|
+
openSqliteStoreConnection,
|
|
20
|
+
type SqliteStoreConnection,
|
|
21
|
+
} from "./transactions"
|
|
22
|
+
|
|
23
|
+
export interface SqliteWorkflowInterventionStorageOptions {
|
|
24
|
+
/** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */
|
|
25
|
+
path?: string
|
|
26
|
+
/** Internal shared connection used by bundled SqliteStorage. */
|
|
27
|
+
connection?: SqliteStoreConnection
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class SqliteWorkflowInterventionStorage implements WorkflowInterventionStorage {
|
|
31
|
+
private readonly connection: SqliteStoreConnection
|
|
32
|
+
private readonly db: Database
|
|
33
|
+
|
|
34
|
+
constructor(options: SqliteWorkflowInterventionStorageOptions = {}) {
|
|
35
|
+
this.connection = openSqliteStoreConnection(options)
|
|
36
|
+
this.db = this.connection.db
|
|
37
|
+
|
|
38
|
+
if (this.connection.installFreshSchema) {
|
|
39
|
+
installFreshSqliteSchema(this.db)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async create(input: CreateWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {
|
|
44
|
+
assertNonNegativeInteger(input.nodeIndex, "nodeIndex")
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
this.db
|
|
48
|
+
.query(
|
|
49
|
+
`
|
|
50
|
+
INSERT INTO workflow_interventions (
|
|
51
|
+
project_id,
|
|
52
|
+
id,
|
|
53
|
+
workflow_id,
|
|
54
|
+
workflow_run_id,
|
|
55
|
+
node_run_id,
|
|
56
|
+
node_index,
|
|
57
|
+
node_id,
|
|
58
|
+
node_key,
|
|
59
|
+
intervention_id,
|
|
60
|
+
input,
|
|
61
|
+
default_response,
|
|
62
|
+
status,
|
|
63
|
+
requested_at,
|
|
64
|
+
expires_at
|
|
65
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
66
|
+
`
|
|
67
|
+
)
|
|
68
|
+
.run(
|
|
69
|
+
input.projectId,
|
|
70
|
+
input.id,
|
|
71
|
+
input.workflowId,
|
|
72
|
+
input.workflowRunId,
|
|
73
|
+
input.nodeRunId,
|
|
74
|
+
input.nodeIndex,
|
|
75
|
+
input.nodeId,
|
|
76
|
+
input.nodeKey,
|
|
77
|
+
input.interventionId,
|
|
78
|
+
serializeRecord(input.input),
|
|
79
|
+
serializeRecord(input.defaultResponse),
|
|
80
|
+
"pending",
|
|
81
|
+
(input.requestedAt ?? new Date()).toISOString(),
|
|
82
|
+
input.expiresAt?.toISOString() ?? null
|
|
83
|
+
)
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (isUniqueConstraintError(error)) {
|
|
86
|
+
throw new WorkflowInterventionError(
|
|
87
|
+
`[SixbSqlite] Workflow intervention '${input.id}' already exists for project '${input.projectId}'.`
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
throw error
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return this.requireIntervention(input.projectId, input.id)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async submit(input: SubmitWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {
|
|
98
|
+
return this.db.transaction(() => {
|
|
99
|
+
const existing = this.requirePendingIntervention(input.projectId, input.id)
|
|
100
|
+
|
|
101
|
+
this.db
|
|
102
|
+
.query(
|
|
103
|
+
`
|
|
104
|
+
UPDATE workflow_interventions
|
|
105
|
+
SET
|
|
106
|
+
status = ?,
|
|
107
|
+
submitted_at = ?,
|
|
108
|
+
submitted_by = ?,
|
|
109
|
+
response = ?
|
|
110
|
+
WHERE project_id = ? AND id = ?
|
|
111
|
+
`
|
|
112
|
+
)
|
|
113
|
+
.run(
|
|
114
|
+
"submitted",
|
|
115
|
+
(input.submittedAt ?? new Date()).toISOString(),
|
|
116
|
+
serializeActor(input.submittedBy),
|
|
117
|
+
serializeRecord(input.response),
|
|
118
|
+
existing.project_id,
|
|
119
|
+
existing.id
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return this.requireIntervention(input.projectId, input.id)
|
|
123
|
+
})()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async cancel(input: CancelWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {
|
|
127
|
+
return this.db.transaction(() => {
|
|
128
|
+
const existing = this.requirePendingIntervention(input.projectId, input.id)
|
|
129
|
+
|
|
130
|
+
this.db
|
|
131
|
+
.query(
|
|
132
|
+
`
|
|
133
|
+
UPDATE workflow_interventions
|
|
134
|
+
SET
|
|
135
|
+
status = ?,
|
|
136
|
+
cancelled_at = ?,
|
|
137
|
+
cancelled_by = ?
|
|
138
|
+
WHERE project_id = ? AND id = ?
|
|
139
|
+
`
|
|
140
|
+
)
|
|
141
|
+
.run(
|
|
142
|
+
"cancelled",
|
|
143
|
+
(input.cancelledAt ?? new Date()).toISOString(),
|
|
144
|
+
serializeActor(input.cancelledBy),
|
|
145
|
+
existing.project_id,
|
|
146
|
+
existing.id
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
return this.requireIntervention(input.projectId, input.id)
|
|
150
|
+
})()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async expire(input: ExpireWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {
|
|
154
|
+
return this.db.transaction(() => {
|
|
155
|
+
const existing = this.requirePendingIntervention(input.projectId, input.id)
|
|
156
|
+
|
|
157
|
+
this.db
|
|
158
|
+
.query(
|
|
159
|
+
`
|
|
160
|
+
UPDATE workflow_interventions
|
|
161
|
+
SET
|
|
162
|
+
status = ?,
|
|
163
|
+
expired_at = ?
|
|
164
|
+
WHERE project_id = ? AND id = ?
|
|
165
|
+
`
|
|
166
|
+
)
|
|
167
|
+
.run(
|
|
168
|
+
"expired",
|
|
169
|
+
(input.expiredAt ?? new Date()).toISOString(),
|
|
170
|
+
existing.project_id,
|
|
171
|
+
existing.id
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
return this.requireIntervention(input.projectId, input.id)
|
|
175
|
+
})()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async getById(params: {
|
|
179
|
+
projectId: string
|
|
180
|
+
id: string
|
|
181
|
+
}): Promise<WorkflowInterventionRecord | null> {
|
|
182
|
+
const row = this.db
|
|
183
|
+
.query("SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?")
|
|
184
|
+
.get(params.projectId, params.id) as WorkflowInterventionDatabaseRow | null
|
|
185
|
+
|
|
186
|
+
return row ? rowToWorkflowInterventionRecord(row) : null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async list(input: ListWorkflowInterventionsInput): Promise<ListWorkflowInterventionsResult> {
|
|
190
|
+
if ((input.statuses && input.statuses.length === 0) || input.workflowIds?.length === 0) {
|
|
191
|
+
return {
|
|
192
|
+
interventions: [],
|
|
193
|
+
hasMore: false,
|
|
194
|
+
total: 0,
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const whereClauses = ["project_id = ?"]
|
|
199
|
+
const args: SqliteValue[] = [input.projectId]
|
|
200
|
+
|
|
201
|
+
if (input.statuses) {
|
|
202
|
+
whereClauses.push(`status IN (${input.statuses.map(() => "?").join(", ")})`)
|
|
203
|
+
args.push(...input.statuses)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (input.workflowId) {
|
|
207
|
+
whereClauses.push("workflow_id = ?")
|
|
208
|
+
args.push(input.workflowId)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (input.workflowIds) {
|
|
212
|
+
whereClauses.push(`workflow_id IN (${input.workflowIds.map(() => "?").join(", ")})`)
|
|
213
|
+
args.push(...input.workflowIds)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (input.workflowRunId) {
|
|
217
|
+
whereClauses.push("workflow_run_id = ?")
|
|
218
|
+
args.push(input.workflowRunId)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (input.nodeRunId) {
|
|
222
|
+
whereClauses.push("node_run_id = ?")
|
|
223
|
+
args.push(input.nodeRunId)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (input.nodeId) {
|
|
227
|
+
whereClauses.push("node_id = ?")
|
|
228
|
+
args.push(input.nodeId)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (input.nodeKey) {
|
|
232
|
+
whereClauses.push("node_key = ?")
|
|
233
|
+
args.push(input.nodeKey)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (input.interventionId) {
|
|
237
|
+
whereClauses.push("intervention_id = ?")
|
|
238
|
+
args.push(input.interventionId)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (input.requestedAfter) {
|
|
242
|
+
whereClauses.push("requested_at >= ?")
|
|
243
|
+
args.push(input.requestedAfter.toISOString())
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (input.requestedBefore) {
|
|
247
|
+
whereClauses.push("requested_at <= ?")
|
|
248
|
+
args.push(input.requestedBefore.toISOString())
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const where = `WHERE ${whereClauses.join(" AND ")}`
|
|
252
|
+
const order = input.order === "asc" ? "ASC" : "DESC"
|
|
253
|
+
const offset = input.offset ?? 0
|
|
254
|
+
const totalRow = this.db
|
|
255
|
+
.query(`SELECT COUNT(*) AS count FROM workflow_interventions ${where}`)
|
|
256
|
+
.get(...args) as { count: number }
|
|
257
|
+
|
|
258
|
+
let query = `
|
|
259
|
+
SELECT * FROM workflow_interventions
|
|
260
|
+
${where}
|
|
261
|
+
ORDER BY requested_at ${order}, id ${order}
|
|
262
|
+
`
|
|
263
|
+
const queryArgs = [...args]
|
|
264
|
+
|
|
265
|
+
if (input.limit !== undefined) {
|
|
266
|
+
query += " LIMIT ? OFFSET ?"
|
|
267
|
+
queryArgs.push(input.limit, offset)
|
|
268
|
+
} else if (offset > 0) {
|
|
269
|
+
query += " LIMIT -1 OFFSET ?"
|
|
270
|
+
queryArgs.push(offset)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const rows = this.db.query(query).all(...queryArgs) as WorkflowInterventionDatabaseRow[]
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
interventions: rows.map(rowToWorkflowInterventionRecord),
|
|
277
|
+
hasMore: offset + rows.length < totalRow.count,
|
|
278
|
+
total: totalRow.count,
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
close(): void {
|
|
283
|
+
closeSqliteStoreConnection(this.connection)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private requirePendingIntervention(
|
|
287
|
+
projectId: string,
|
|
288
|
+
id: string
|
|
289
|
+
): WorkflowInterventionDatabaseRow {
|
|
290
|
+
const row = this.db
|
|
291
|
+
.query("SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?")
|
|
292
|
+
.get(projectId, id) as WorkflowInterventionDatabaseRow | null
|
|
293
|
+
|
|
294
|
+
if (!row) {
|
|
295
|
+
throw new WorkflowInterventionError(
|
|
296
|
+
`[SixbSqlite] Workflow intervention '${id}' not found for project '${projectId}'.`
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (row.status !== "pending") {
|
|
301
|
+
throw new WorkflowInterventionError(
|
|
302
|
+
`[SixbSqlite] Workflow intervention '${id}' for project '${projectId}' is not pending.`
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return row
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
private requireIntervention(projectId: string, id: string): WorkflowInterventionRecord {
|
|
310
|
+
const row = this.db
|
|
311
|
+
.query("SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?")
|
|
312
|
+
.get(projectId, id) as WorkflowInterventionDatabaseRow | null
|
|
313
|
+
|
|
314
|
+
if (!row) {
|
|
315
|
+
throw new WorkflowInterventionError(
|
|
316
|
+
`[SixbSqlite] Failed to load workflow intervention '${id}' for project '${projectId}'.`
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return rowToWorkflowInterventionRecord(row)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
type SqliteValue = string | number | null
|
|
325
|
+
|
|
326
|
+
function serializeRecord(value: WorkflowIOSnapshot): string {
|
|
327
|
+
return JSON.stringify(value)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function parseRecord(value: string): WorkflowIOSnapshot {
|
|
331
|
+
return JSON.parse(value) as WorkflowIOSnapshot
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function serializeActor(actor: WorkflowInterventionActor | undefined): string | null {
|
|
335
|
+
return actor ? JSON.stringify(actor) : null
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function parseActor(value: string | null): WorkflowInterventionActor | undefined {
|
|
339
|
+
return value ? (JSON.parse(value) as WorkflowInterventionActor) : undefined
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function rowToWorkflowInterventionRecord(
|
|
343
|
+
row: WorkflowInterventionDatabaseRow
|
|
344
|
+
): WorkflowInterventionRecord {
|
|
345
|
+
return {
|
|
346
|
+
id: row.id,
|
|
347
|
+
projectId: row.project_id,
|
|
348
|
+
workflowId: row.workflow_id,
|
|
349
|
+
workflowRunId: row.workflow_run_id,
|
|
350
|
+
nodeRunId: row.node_run_id,
|
|
351
|
+
nodeIndex: row.node_index,
|
|
352
|
+
nodeId: row.node_id,
|
|
353
|
+
nodeKey: row.node_key,
|
|
354
|
+
interventionId: row.intervention_id,
|
|
355
|
+
input: parseRecord(row.input),
|
|
356
|
+
defaultResponse: parseRecord(row.default_response),
|
|
357
|
+
status: row.status,
|
|
358
|
+
requestedAt: new Date(row.requested_at),
|
|
359
|
+
expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,
|
|
360
|
+
submittedAt: row.submitted_at ? new Date(row.submitted_at) : undefined,
|
|
361
|
+
submittedBy: parseActor(row.submitted_by),
|
|
362
|
+
response: row.response ? parseRecord(row.response) : undefined,
|
|
363
|
+
cancelledAt: row.cancelled_at ? new Date(row.cancelled_at) : undefined,
|
|
364
|
+
cancelledBy: parseActor(row.cancelled_by),
|
|
365
|
+
expiredAt: row.expired_at ? new Date(row.expired_at) : undefined,
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function assertNonNegativeInteger(value: number, fieldName: string): void {
|
|
370
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
371
|
+
throw new WorkflowInterventionError(
|
|
372
|
+
`[SixbSqlite] Workflow intervention ${fieldName} must be a non-negative integer.`
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
interface WorkflowInterventionDatabaseRow {
|
|
378
|
+
project_id: string
|
|
379
|
+
id: string
|
|
380
|
+
workflow_id: string
|
|
381
|
+
workflow_run_id: string
|
|
382
|
+
node_run_id: string
|
|
383
|
+
node_index: number
|
|
384
|
+
node_id: string
|
|
385
|
+
node_key: string
|
|
386
|
+
intervention_id: string
|
|
387
|
+
input: string
|
|
388
|
+
default_response: string
|
|
389
|
+
status: WorkflowInterventionRecord["status"]
|
|
390
|
+
requested_at: string
|
|
391
|
+
expires_at: string | null
|
|
392
|
+
submitted_at: string | null
|
|
393
|
+
submitted_by: string | null
|
|
394
|
+
response: string | null
|
|
395
|
+
cancelled_at: string | null
|
|
396
|
+
cancelled_by: string | null
|
|
397
|
+
expired_at: string | null
|
|
398
|
+
}
|