@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.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/action-run-storage.d.ts +29 -0
  4. package/dist/action-run-storage.d.ts.map +1 -0
  5. package/dist/agents/agent-storage.d.ts +25 -0
  6. package/dist/agents/agent-storage.d.ts.map +1 -0
  7. package/dist/agents/index.d.ts +6 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/messages.d.ts +14 -0
  10. package/dist/agents/messages.d.ts.map +1 -0
  11. package/dist/agents/rows.d.ts +77 -0
  12. package/dist/agents/rows.d.ts.map +1 -0
  13. package/dist/agents/runs.d.ts +26 -0
  14. package/dist/agents/runs.d.ts.map +1 -0
  15. package/dist/agents/threads.d.ts +14 -0
  16. package/dist/agents/threads.d.ts.map +1 -0
  17. package/dist/auth-storage/access-tokens.d.ts +33 -0
  18. package/dist/auth-storage/access-tokens.d.ts.map +1 -0
  19. package/dist/auth-storage/auth-storage.d.ts +46 -0
  20. package/dist/auth-storage/auth-storage.d.ts.map +1 -0
  21. package/dist/auth-storage/group-memberships.d.ts +21 -0
  22. package/dist/auth-storage/group-memberships.d.ts.map +1 -0
  23. package/dist/auth-storage/identities.d.ts +17 -0
  24. package/dist/auth-storage/identities.d.ts.map +1 -0
  25. package/dist/auth-storage/index.d.ts +3 -0
  26. package/dist/auth-storage/index.d.ts.map +1 -0
  27. package/dist/auth-storage/invitations.d.ts +28 -0
  28. package/dist/auth-storage/invitations.d.ts.map +1 -0
  29. package/dist/auth-storage/magic-links.d.ts +28 -0
  30. package/dist/auth-storage/magic-links.d.ts.map +1 -0
  31. package/dist/auth-storage/oidc-attempts.d.ts +18 -0
  32. package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
  33. package/dist/auth-storage/rows.d.ts +134 -0
  34. package/dist/auth-storage/rows.d.ts.map +1 -0
  35. package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
  36. package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
  37. package/dist/auth-storage/service-accounts.d.ts +14 -0
  38. package/dist/auth-storage/service-accounts.d.ts.map +1 -0
  39. package/dist/auth-storage/sessions.d.ts +55 -0
  40. package/dist/auth-storage/sessions.d.ts.map +1 -0
  41. package/dist/auth-storage/shared.d.ts +131 -0
  42. package/dist/auth-storage/shared.d.ts.map +1 -0
  43. package/dist/auth-storage/users.d.ts +19 -0
  44. package/dist/auth-storage/users.d.ts.map +1 -0
  45. package/dist/index.d.ts +71 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +10204 -0
  48. package/dist/index.js.map +54 -0
  49. package/dist/latest-run-query.d.ts +22 -0
  50. package/dist/latest-run-query.d.ts.map +1 -0
  51. package/dist/migrations.d.ts +18 -0
  52. package/dist/migrations.d.ts.map +1 -0
  53. package/dist/object-query-compiler.d.ts +44 -0
  54. package/dist/object-query-compiler.d.ts.map +1 -0
  55. package/dist/object-storage.d.ts +93 -0
  56. package/dist/object-storage.d.ts.map +1 -0
  57. package/dist/ontology-storage/commits.d.ts +14 -0
  58. package/dist/ontology-storage/commits.d.ts.map +1 -0
  59. package/dist/ontology-storage/index.d.ts +22 -0
  60. package/dist/ontology-storage/index.d.ts.map +1 -0
  61. package/dist/ontology-storage/materialization-session.d.ts +49 -0
  62. package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
  63. package/dist/ontology-storage/materialization-state.d.ts +63 -0
  64. package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
  65. package/dist/ontology-storage/materialization-writer.d.ts +15 -0
  66. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
  67. package/dist/ontology-storage/materializations.d.ts +32 -0
  68. package/dist/ontology-storage/materializations.d.ts.map +1 -0
  69. package/dist/ontology-storage/outbox.d.ts +14 -0
  70. package/dist/ontology-storage/outbox.d.ts.map +1 -0
  71. package/dist/ontology-storage/shared.d.ts +91 -0
  72. package/dist/ontology-storage/shared.d.ts.map +1 -0
  73. package/dist/ontology-storage/sources.d.ts +26 -0
  74. package/dist/ontology-storage/sources.d.ts.map +1 -0
  75. package/dist/pipeline-run-storage.d.ts +26 -0
  76. package/dist/pipeline-run-storage.d.ts.map +1 -0
  77. package/dist/projection-run-storage.d.ts +32 -0
  78. package/dist/projection-run-storage.d.ts.map +1 -0
  79. package/dist/rules-storage.d.ts +33 -0
  80. package/dist/rules-storage.d.ts.map +1 -0
  81. package/dist/run-list-query.d.ts +27 -0
  82. package/dist/run-list-query.d.ts.map +1 -0
  83. package/dist/storage-errors.d.ts +2 -0
  84. package/dist/storage-errors.d.ts.map +1 -0
  85. package/dist/sync-run-storage.d.ts +23 -0
  86. package/dist/sync-run-storage.d.ts.map +1 -0
  87. package/dist/timeseries-storage.d.ts +41 -0
  88. package/dist/timeseries-storage.d.ts.map +1 -0
  89. package/dist/transactions.d.ts +15 -0
  90. package/dist/transactions.d.ts.map +1 -0
  91. package/dist/tsconfig.json +5 -0
  92. package/dist/validation.d.ts +5 -0
  93. package/dist/validation.d.ts.map +1 -0
  94. package/dist/webhook-delivery-storage.d.ts +27 -0
  95. package/dist/webhook-delivery-storage.d.ts.map +1 -0
  96. package/dist/webhook-run-storage.d.ts +22 -0
  97. package/dist/webhook-run-storage.d.ts.map +1 -0
  98. package/dist/workflow-intervention-storage.d.ts +26 -0
  99. package/dist/workflow-intervention-storage.d.ts.map +1 -0
  100. package/dist/workflow-run-storage.d.ts +63 -0
  101. package/dist/workflow-run-storage.d.ts.map +1 -0
  102. package/package.json +58 -0
  103. package/src/action-run-storage.ts +761 -0
  104. package/src/agents/agent-storage.ts +46 -0
  105. package/src/agents/index.ts +5 -0
  106. package/src/agents/messages.ts +162 -0
  107. package/src/agents/rows.ts +205 -0
  108. package/src/agents/runs.ts +389 -0
  109. package/src/agents/threads.ts +133 -0
  110. package/src/auth-storage/access-tokens.ts +289 -0
  111. package/src/auth-storage/auth-storage.ts +784 -0
  112. package/src/auth-storage/group-memberships.ts +52 -0
  113. package/src/auth-storage/identities.ts +98 -0
  114. package/src/auth-storage/index.ts +2 -0
  115. package/src/auth-storage/invitations.ts +258 -0
  116. package/src/auth-storage/magic-links.ts +149 -0
  117. package/src/auth-storage/oidc-attempts.ts +109 -0
  118. package/src/auth-storage/rows.ts +338 -0
  119. package/src/auth-storage/service-account-group-memberships.ts +161 -0
  120. package/src/auth-storage/service-accounts.ts +168 -0
  121. package/src/auth-storage/sessions.ts +230 -0
  122. package/src/auth-storage/shared.ts +707 -0
  123. package/src/auth-storage/users.ts +226 -0
  124. package/src/index.ts +292 -0
  125. package/src/latest-run-query.ts +49 -0
  126. package/src/migrations/001-initial-schema.sql +1068 -0
  127. package/src/migrations.ts +245 -0
  128. package/src/object-query-compiler.ts +1198 -0
  129. package/src/object-storage.ts +605 -0
  130. package/src/ontology-storage/commits.ts +127 -0
  131. package/src/ontology-storage/index.ts +35 -0
  132. package/src/ontology-storage/materialization-session.ts +393 -0
  133. package/src/ontology-storage/materialization-state.ts +901 -0
  134. package/src/ontology-storage/materialization-writer.ts +394 -0
  135. package/src/ontology-storage/materializations.ts +838 -0
  136. package/src/ontology-storage/outbox.ts +237 -0
  137. package/src/ontology-storage/shared.ts +269 -0
  138. package/src/ontology-storage/sources.ts +653 -0
  139. package/src/pipeline-run-storage.ts +506 -0
  140. package/src/projection-run-storage.ts +592 -0
  141. package/src/rules-storage.ts +375 -0
  142. package/src/run-list-query.ts +98 -0
  143. package/src/sql.d.ts +4 -0
  144. package/src/storage-errors.ts +3 -0
  145. package/src/sync-run-storage.ts +299 -0
  146. package/src/timeseries-storage.ts +212 -0
  147. package/src/transactions.ts +96 -0
  148. package/src/validation.ts +30 -0
  149. package/src/webhook-delivery-storage.ts +272 -0
  150. package/src/webhook-run-storage.ts +240 -0
  151. package/src/workflow-intervention-storage.ts +398 -0
  152. package/src/workflow-run-storage.ts +1148 -0
@@ -0,0 +1,289 @@
1
+ import type { Database } from "bun:sqlite"
2
+ import type {
3
+ AccessTokenRecord,
4
+ AuthAccessTokenStore,
5
+ CreateAuthAccessTokenInput,
6
+ ListAuthAccessTokensInput,
7
+ ListAuthAccessTokensResult,
8
+ } from "@sixb/core/storage"
9
+ import { AuthStorageError } from "@sixb/core/storage"
10
+ import type {
11
+ SqliteAuthAccessTokenRow,
12
+ SqliteAuthServiceAccountRow,
13
+ SqliteAuthUserRow,
14
+ } from "./rows"
15
+ import { rowToAccessTokenRecord, serializeOptionalStringArray } from "./rows"
16
+ import {
17
+ appendPagination,
18
+ assertNonEmpty,
19
+ mapUniqueConstraintError,
20
+ normalizeGroupIds,
21
+ type SqliteValue,
22
+ toIso,
23
+ } from "./shared"
24
+
25
+ export class SqliteAuthAccessTokenStore implements AuthAccessTokenStore {
26
+ constructor(private readonly db: Database) {}
27
+
28
+ async create(input: CreateAuthAccessTokenInput): Promise<AccessTokenRecord> {
29
+ const id = assertNonEmpty(input.id, "Access token id")
30
+ const projectId = assertNonEmpty(input.projectId, "Project id")
31
+ const name = assertNonEmpty(input.name, "Access token name")
32
+ const subjectId = assertNonEmpty(input.subjectId, "Access token subject id")
33
+ const tokenHash = assertNonEmpty(input.tokenHash, "Access token hash")
34
+ assertKindMatchesSubject(input)
35
+ this.assertSubjectExists(projectId, input.subjectType, subjectId)
36
+ const groupIds = input.groupIds === undefined ? undefined : normalizeGroupIds(input.groupIds)
37
+
38
+ try {
39
+ this.db
40
+ .query(
41
+ `
42
+ INSERT INTO auth_access_tokens (
43
+ project_id,
44
+ id,
45
+ name,
46
+ kind,
47
+ subject_type,
48
+ subject_id,
49
+ token_hash,
50
+ group_ids,
51
+ created_by_principal_type,
52
+ created_by_principal_id,
53
+ created_by_session_id,
54
+ created_at,
55
+ expires_at
56
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
57
+ `
58
+ )
59
+ .run(
60
+ projectId,
61
+ id,
62
+ name,
63
+ input.kind,
64
+ input.subjectType,
65
+ subjectId,
66
+ tokenHash,
67
+ serializeOptionalStringArray(groupIds),
68
+ input.createdByPrincipal?.type ?? null,
69
+ input.createdByPrincipal?.id ?? null,
70
+ input.createdBySessionId ?? null,
71
+ toIso(input.createdAt),
72
+ toIso(input.expiresAt)
73
+ )
74
+ } catch (error) {
75
+ mapUniqueConstraintError(
76
+ error,
77
+ "duplicate_access_token",
78
+ `[Sixb] Access token '${id}' already exists for project '${projectId}'.`
79
+ )
80
+ }
81
+
82
+ const token = await this.getById({ projectId, id })
83
+ if (!token) {
84
+ throw new AuthStorageError(
85
+ "missing_access_token",
86
+ `[Sixb] Access token '${id}' not found for project '${projectId}'.`
87
+ )
88
+ }
89
+ return token
90
+ }
91
+
92
+ async getById(params: {
93
+ readonly projectId: string
94
+ readonly id: string
95
+ }): Promise<AccessTokenRecord | null> {
96
+ const row = this.db
97
+ .query("SELECT * FROM auth_access_tokens WHERE project_id = ? AND id = ?")
98
+ .get(params.projectId, params.id) as SqliteAuthAccessTokenRow | null
99
+ return row ? rowToAccessTokenRecord(row) : null
100
+ }
101
+
102
+ async list(input: ListAuthAccessTokensInput): Promise<ListAuthAccessTokensResult> {
103
+ const whereClauses = ["project_id = ?"]
104
+ const args: SqliteValue[] = [input.projectId]
105
+ if (input.kind) {
106
+ whereClauses.push("kind = ?")
107
+ args.push(input.kind)
108
+ }
109
+ if (input.subjectType) {
110
+ whereClauses.push("subject_type = ?")
111
+ args.push(input.subjectType)
112
+ }
113
+ if (input.subjectId) {
114
+ whereClauses.push("subject_id = ?")
115
+ args.push(input.subjectId)
116
+ }
117
+ if (!input.includeRevoked) {
118
+ whereClauses.push("revoked_at IS NULL")
119
+ }
120
+
121
+ const where = `WHERE ${whereClauses.join(" AND ")}`
122
+ const order = input.order === "desc" ? "DESC" : "ASC"
123
+ const totalRow = this.db
124
+ .query(`SELECT COUNT(*) AS count FROM auth_access_tokens ${where}`)
125
+ .get(...args) as { readonly count: number }
126
+ const queryArgs = [...args]
127
+ const query = appendPagination(
128
+ `
129
+ SELECT *
130
+ FROM auth_access_tokens
131
+ ${where}
132
+ ORDER BY created_at ${order}, id ${order}
133
+ `,
134
+ queryArgs,
135
+ input
136
+ )
137
+ const rows = this.db.query(query).all(...queryArgs) as SqliteAuthAccessTokenRow[]
138
+
139
+ return {
140
+ accessTokens: rows.map(rowToAccessTokenRecord),
141
+ hasMore:
142
+ input.limit === undefined ? false : (input.offset ?? 0) + input.limit < totalRow.count,
143
+ total: totalRow.count,
144
+ }
145
+ }
146
+
147
+ async findValidByTokenHash(params: {
148
+ readonly projectId: string
149
+ readonly id: string
150
+ readonly kind: AccessTokenRecord["kind"]
151
+ readonly tokenHash: string
152
+ readonly now: Date
153
+ }): Promise<AccessTokenRecord | null> {
154
+ const row = this.db
155
+ .query(
156
+ `
157
+ SELECT *
158
+ FROM auth_access_tokens
159
+ WHERE project_id = ?
160
+ AND id = ?
161
+ AND kind = ?
162
+ AND token_hash = ?
163
+ AND revoked_at IS NULL
164
+ AND expires_at > ?
165
+ `
166
+ )
167
+ .get(
168
+ params.projectId,
169
+ params.id,
170
+ params.kind,
171
+ params.tokenHash,
172
+ toIso(params.now)
173
+ ) as SqliteAuthAccessTokenRow | null
174
+
175
+ return row ? rowToAccessTokenRecord(row) : null
176
+ }
177
+
178
+ async revoke(params: {
179
+ readonly projectId: string
180
+ readonly id: string
181
+ readonly revokedAt: Date
182
+ }): Promise<AccessTokenRecord> {
183
+ const existing = await this.getById(params)
184
+ if (!existing) {
185
+ throw new AuthStorageError(
186
+ "missing_access_token",
187
+ `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`
188
+ )
189
+ }
190
+
191
+ this.db
192
+ .query(
193
+ `
194
+ UPDATE auth_access_tokens
195
+ SET revoked_at = ?
196
+ WHERE project_id = ?
197
+ AND id = ?
198
+ `
199
+ )
200
+ .run(toIso(params.revokedAt), params.projectId, params.id)
201
+
202
+ return { ...existing, revokedAt: new Date(params.revokedAt) }
203
+ }
204
+
205
+ async touch(params: {
206
+ readonly projectId: string
207
+ readonly id: string
208
+ readonly lastUsedAt: Date
209
+ readonly userAgent?: string
210
+ readonly ipAddress?: string
211
+ }): Promise<AccessTokenRecord> {
212
+ const existing = await this.getById(params)
213
+ if (!existing) {
214
+ throw new AuthStorageError(
215
+ "missing_access_token",
216
+ `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`
217
+ )
218
+ }
219
+
220
+ const lastUsedUserAgent = params.userAgent ?? existing.lastUsedUserAgent
221
+ const lastUsedIpAddress = params.ipAddress ?? existing.lastUsedIpAddress
222
+
223
+ this.db
224
+ .query(
225
+ `
226
+ UPDATE auth_access_tokens
227
+ SET last_used_at = ?,
228
+ last_used_user_agent = ?,
229
+ last_used_ip_address = ?
230
+ WHERE project_id = ?
231
+ AND id = ?
232
+ `
233
+ )
234
+ .run(
235
+ toIso(params.lastUsedAt),
236
+ lastUsedUserAgent ?? null,
237
+ lastUsedIpAddress ?? null,
238
+ params.projectId,
239
+ params.id
240
+ )
241
+
242
+ return {
243
+ ...existing,
244
+ lastUsedAt: new Date(params.lastUsedAt),
245
+ lastUsedUserAgent,
246
+ lastUsedIpAddress,
247
+ }
248
+ }
249
+
250
+ private assertSubjectExists(
251
+ projectId: string,
252
+ subjectType: CreateAuthAccessTokenInput["subjectType"],
253
+ subjectId: string
254
+ ): void {
255
+ if (subjectType === "user") {
256
+ const row = this.db
257
+ .query("SELECT * FROM auth_users WHERE project_id = ? AND id = ?")
258
+ .get(projectId, subjectId) as SqliteAuthUserRow | null
259
+ if (row) return
260
+ throw new AuthStorageError(
261
+ "missing_user",
262
+ `[Sixb] User '${subjectId}' not found for project '${projectId}'.`
263
+ )
264
+ }
265
+
266
+ const row = this.db
267
+ .query("SELECT * FROM auth_service_accounts WHERE project_id = ? AND id = ?")
268
+ .get(projectId, subjectId) as SqliteAuthServiceAccountRow | null
269
+ if (row) return
270
+ throw new AuthStorageError(
271
+ "missing_service_account",
272
+ `[Sixb] Service account '${subjectId}' not found for project '${projectId}'.`
273
+ )
274
+ }
275
+ }
276
+
277
+ function assertKindMatchesSubject(input: CreateAuthAccessTokenInput): void {
278
+ if (
279
+ (input.kind === "personal" && input.subjectType === "user") ||
280
+ (input.kind === "serviceAccount" && input.subjectType === "serviceAccount")
281
+ ) {
282
+ return
283
+ }
284
+
285
+ throw new AuthStorageError(
286
+ "invalid_input",
287
+ `[Sixb] Access token kind '${input.kind}' cannot target subject type '${input.subjectType}'.`
288
+ )
289
+ }