@mastra/cloudflare-d1 1.1.1 → 1.2.0-alpha.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/dist/index.cjs CHANGED
@@ -1,1506 +1,1438 @@
1
- 'use strict';
2
-
3
- var error = require('@mastra/core/error');
4
- var storage = require('@mastra/core/storage');
5
- var Cloudflare = require('cloudflare');
6
- var base = require('@mastra/core/base');
7
- var utils = require('@mastra/core/utils');
8
- var agent = require('@mastra/core/agent');
9
- var evals = require('@mastra/core/evals');
10
-
11
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
-
13
- var Cloudflare__default = /*#__PURE__*/_interopDefault(Cloudflare);
14
-
15
- // src/storage/index.ts
16
-
17
- // src/storage/domains/utils.ts
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _mastra_core_error = require("@mastra/core/error");
25
+ let _mastra_core_storage = require("@mastra/core/storage");
26
+ let cloudflare = require("cloudflare");
27
+ cloudflare = __toESM(cloudflare, 1);
28
+ let _mastra_core_base = require("@mastra/core/base");
29
+ let _mastra_core_utils = require("@mastra/core/utils");
30
+ let _mastra_core_agent = require("@mastra/core/agent");
31
+ let _mastra_core_evals = require("@mastra/core/evals");
32
+ //#region src/storage/domains/utils.ts
18
33
  function isArrayOfRecords(value) {
19
- return value && Array.isArray(value) && value.length > 0;
34
+ return value && Array.isArray(value) && value.length > 0;
20
35
  }
21
36
  function deserializeValue(value, type) {
22
- if (value === null || value === void 0) return null;
23
- if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
24
- try {
25
- return JSON.parse(value);
26
- } catch {
27
- return value;
28
- }
29
- }
30
- return value;
37
+ if (value === null || value === void 0) return null;
38
+ if (type === "date" && typeof value === "string") return new Date(value);
39
+ if (type === "jsonb" && typeof value === "string") try {
40
+ return JSON.parse(value);
41
+ } catch {
42
+ return value;
43
+ }
44
+ if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) try {
45
+ return JSON.parse(value);
46
+ } catch {
47
+ return value;
48
+ }
49
+ return value;
31
50
  }
51
+ //#endregion
52
+ //#region src/storage/sql-builder.ts
53
+ /**
54
+ * SQL Builder class for constructing type-safe SQL queries
55
+ * This helps create maintainable and secure SQL queries with proper parameter handling
56
+ */
32
57
  var SqlBuilder = class {
33
- sql = "";
34
- params = [];
35
- whereAdded = false;
36
- // Basic query building
37
- select(columns) {
38
- if (!columns || Array.isArray(columns) && columns.length === 0) {
39
- this.sql = "SELECT *";
40
- } else {
41
- const cols = Array.isArray(columns) ? columns : [columns];
42
- const parsedCols = cols.map((col) => parseSelectIdentifier(col));
43
- this.sql = `SELECT ${parsedCols.join(", ")}`;
44
- }
45
- return this;
46
- }
47
- from(table) {
48
- const parsedTableName = utils.parseSqlIdentifier(table, "table name");
49
- this.sql += ` FROM ${parsedTableName}`;
50
- return this;
51
- }
52
- /**
53
- * Add a WHERE clause to the query
54
- * @param condition The condition to add
55
- * @param params Parameters to bind to the condition
56
- */
57
- where(condition, ...params) {
58
- this.sql += ` WHERE ${condition}`;
59
- this.params.push(...params);
60
- this.whereAdded = true;
61
- return this;
62
- }
63
- /**
64
- * Add a WHERE clause if it hasn't been added yet, otherwise add an AND clause
65
- * @param condition The condition to add
66
- * @param params Parameters to bind to the condition
67
- */
68
- whereAnd(condition, ...params) {
69
- if (this.whereAdded) {
70
- return this.andWhere(condition, ...params);
71
- } else {
72
- return this.where(condition, ...params);
73
- }
74
- }
75
- andWhere(condition, ...params) {
76
- this.sql += ` AND ${condition}`;
77
- this.params.push(...params);
78
- return this;
79
- }
80
- orWhere(condition, ...params) {
81
- this.sql += ` OR ${condition}`;
82
- this.params.push(...params);
83
- return this;
84
- }
85
- orderBy(column, direction = "ASC") {
86
- const parsedColumn = utils.parseSqlIdentifier(column, "column name");
87
- if (!["ASC", "DESC"].includes(direction)) {
88
- throw new Error(`Invalid sort direction: ${direction}`);
89
- }
90
- this.sql += ` ORDER BY ${parsedColumn} ${direction}`;
91
- return this;
92
- }
93
- limit(count) {
94
- this.sql += ` LIMIT ?`;
95
- this.params.push(count);
96
- return this;
97
- }
98
- offset(count) {
99
- this.sql += ` OFFSET ?`;
100
- this.params.push(count);
101
- return this;
102
- }
103
- count() {
104
- this.sql += "SELECT COUNT(*) AS count";
105
- return this;
106
- }
107
- /**
108
- * Insert a row, or update specific columns on conflict (upsert).
109
- * @param table Table name
110
- * @param columns Columns to insert
111
- * @param values Values to insert
112
- * @param conflictColumns Columns to check for conflict (usually PK or UNIQUE)
113
- * @param updateMap Object mapping columns to update to their new value (e.g. { name: 'excluded.name' })
114
- */
115
- insert(table, columns, values, conflictColumns, updateMap) {
116
- const parsedTableName = utils.parseSqlIdentifier(table, "table name");
117
- const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
118
- const placeholders = parsedColumns.map(() => "?").join(", ");
119
- if (conflictColumns && updateMap) {
120
- const parsedConflictColumns = conflictColumns.map((col) => utils.parseSqlIdentifier(col, "column name"));
121
- const updateClause = Object.entries(updateMap).map(([col, expr]) => `${col} = ${expr}`).join(", ");
122
- this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${parsedConflictColumns.join(", ")}) DO UPDATE SET ${updateClause}`;
123
- this.params.push(...values);
124
- return this;
125
- }
126
- this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders})`;
127
- this.params.push(...values);
128
- return this;
129
- }
130
- // Update operations
131
- update(table, columns, values) {
132
- const parsedTableName = utils.parseSqlIdentifier(table, "table name");
133
- const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
134
- const setClause = parsedColumns.map((col) => `${col} = ?`).join(", ");
135
- this.sql = `UPDATE ${parsedTableName} SET ${setClause}`;
136
- this.params.push(...values);
137
- return this;
138
- }
139
- // Delete operations
140
- delete(table) {
141
- const parsedTableName = utils.parseSqlIdentifier(table, "table name");
142
- this.sql = `DELETE FROM ${parsedTableName}`;
143
- return this;
144
- }
145
- /**
146
- * Create a table if it doesn't exist
147
- * @param table The table name
148
- * @param columnDefinitions The column definitions as an array of strings
149
- * @param tableConstraints Optional constraints for the table
150
- * @returns The builder instance
151
- */
152
- createTable(table, columnDefinitions, tableConstraints) {
153
- const parsedTableName = utils.parseSqlIdentifier(table, "table name");
154
- const parsedColumnDefinitions = columnDefinitions.map((def) => {
155
- const colName = def.split(/\s+/)[0];
156
- if (!colName) throw new Error("Empty column name in definition");
157
- utils.parseSqlIdentifier(colName, "column name");
158
- return def;
159
- });
160
- const columns = parsedColumnDefinitions.join(", ");
161
- const constraints = tableConstraints && tableConstraints.length > 0 ? ", " + tableConstraints.join(", ") : "";
162
- this.sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns}${constraints})`;
163
- return this;
164
- }
165
- /**
166
- * Check if an index exists in the database
167
- * @param indexName The name of the index to check
168
- * @param tableName The table the index is on
169
- * @returns The builder instance
170
- */
171
- checkIndexExists(indexName, tableName) {
172
- this.sql = `SELECT name FROM sqlite_master WHERE type='index' AND name=? AND tbl_name=?`;
173
- this.params.push(indexName, tableName);
174
- return this;
175
- }
176
- /**
177
- * Create an index if it doesn't exist
178
- * @param indexName The name of the index to create
179
- * @param tableName The table to create the index on
180
- * @param columnName The column to index
181
- * @param indexType Optional index type (e.g., 'UNIQUE')
182
- * @returns The builder instance
183
- */
184
- createIndex(indexName, tableName, columnName, indexType = "") {
185
- const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
186
- const parsedTableName = utils.parseSqlIdentifier(tableName, "table name");
187
- const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
188
- this.sql = `CREATE ${indexType ? indexType + " " : ""}INDEX IF NOT EXISTS ${parsedIndexName} ON ${parsedTableName}(${parsedColumnName})`;
189
- return this;
190
- }
191
- /**
192
- * Add a LIKE condition to the query
193
- * @param column The column to check
194
- * @param value The value to match (will be wrapped with % for LIKE)
195
- * @param exact If true, will not add % wildcards
196
- */
197
- like(column, value, exact = false) {
198
- const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
199
- const likeValue = exact ? value : `%${value}%`;
200
- if (this.whereAdded) {
201
- this.sql += ` AND ${parsedColumnName} LIKE ?`;
202
- } else {
203
- this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
204
- this.whereAdded = true;
205
- }
206
- this.params.push(likeValue);
207
- return this;
208
- }
209
- /**
210
- * Add a JSON LIKE condition for searching in JSON fields
211
- * @param column The JSON column to search in
212
- * @param key The JSON key to match
213
- * @param value The value to match
214
- */
215
- jsonLike(column, key, value) {
216
- const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
217
- const parsedKey = utils.parseSqlIdentifier(key, "key name");
218
- const jsonPattern = `%"${parsedKey}":"${value}"%`;
219
- if (this.whereAdded) {
220
- this.sql += ` AND ${parsedColumnName} LIKE ?`;
221
- } else {
222
- this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
223
- this.whereAdded = true;
224
- }
225
- this.params.push(jsonPattern);
226
- return this;
227
- }
228
- /**
229
- * Get the built query
230
- * @returns Object containing the SQL string and parameters array
231
- */
232
- build() {
233
- return {
234
- sql: this.sql,
235
- params: this.params
236
- };
237
- }
238
- /**
239
- * Reset the builder for reuse
240
- * @returns The reset builder instance
241
- */
242
- reset() {
243
- this.sql = "";
244
- this.params = [];
245
- this.whereAdded = false;
246
- return this;
247
- }
58
+ sql = "";
59
+ params = [];
60
+ whereAdded = false;
61
+ select(columns) {
62
+ if (!columns || Array.isArray(columns) && columns.length === 0) this.sql = "SELECT *";
63
+ else {
64
+ const parsedCols = (Array.isArray(columns) ? columns : [columns]).map((col) => parseSelectIdentifier(col));
65
+ this.sql = `SELECT ${parsedCols.join(", ")}`;
66
+ }
67
+ return this;
68
+ }
69
+ from(table) {
70
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
71
+ this.sql += ` FROM ${parsedTableName}`;
72
+ return this;
73
+ }
74
+ /**
75
+ * Add a WHERE clause to the query
76
+ * @param condition The condition to add
77
+ * @param params Parameters to bind to the condition
78
+ */
79
+ where(condition, ...params) {
80
+ this.sql += ` WHERE ${condition}`;
81
+ this.params.push(...params);
82
+ this.whereAdded = true;
83
+ return this;
84
+ }
85
+ /**
86
+ * Add a WHERE clause if it hasn't been added yet, otherwise add an AND clause
87
+ * @param condition The condition to add
88
+ * @param params Parameters to bind to the condition
89
+ */
90
+ whereAnd(condition, ...params) {
91
+ if (this.whereAdded) return this.andWhere(condition, ...params);
92
+ else return this.where(condition, ...params);
93
+ }
94
+ andWhere(condition, ...params) {
95
+ this.sql += ` AND ${condition}`;
96
+ this.params.push(...params);
97
+ return this;
98
+ }
99
+ orWhere(condition, ...params) {
100
+ this.sql += ` OR ${condition}`;
101
+ this.params.push(...params);
102
+ return this;
103
+ }
104
+ orderBy(column, direction = "ASC") {
105
+ const parsedColumn = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
106
+ if (!["ASC", "DESC"].includes(direction)) throw new Error(`Invalid sort direction: ${direction}`);
107
+ this.sql += ` ORDER BY ${parsedColumn} ${direction}`;
108
+ return this;
109
+ }
110
+ limit(count) {
111
+ this.sql += ` LIMIT ?`;
112
+ this.params.push(count);
113
+ return this;
114
+ }
115
+ offset(count) {
116
+ this.sql += ` OFFSET ?`;
117
+ this.params.push(count);
118
+ return this;
119
+ }
120
+ count() {
121
+ this.sql += "SELECT COUNT(*) AS count";
122
+ return this;
123
+ }
124
+ /**
125
+ * Insert a row, or update specific columns on conflict (upsert).
126
+ * @param table Table name
127
+ * @param columns Columns to insert
128
+ * @param values Values to insert
129
+ * @param conflictColumns Columns to check for conflict (usually PK or UNIQUE)
130
+ * @param updateMap Object mapping columns to update to their new value (e.g. { name: 'excluded.name' })
131
+ */
132
+ insert(table, columns, values, conflictColumns, updateMap) {
133
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
134
+ const parsedColumns = columns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name"));
135
+ const placeholders = parsedColumns.map(() => "?").join(", ");
136
+ if (conflictColumns && updateMap) {
137
+ const parsedConflictColumns = conflictColumns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name"));
138
+ const updateClause = Object.entries(updateMap).map(([col, expr]) => `${col} = ${expr}`).join(", ");
139
+ this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${parsedConflictColumns.join(", ")}) DO UPDATE SET ${updateClause}`;
140
+ this.params.push(...values);
141
+ return this;
142
+ }
143
+ this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders})`;
144
+ this.params.push(...values);
145
+ return this;
146
+ }
147
+ update(table, columns, values) {
148
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
149
+ const setClause = columns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name")).map((col) => `${col} = ?`).join(", ");
150
+ this.sql = `UPDATE ${parsedTableName} SET ${setClause}`;
151
+ this.params.push(...values);
152
+ return this;
153
+ }
154
+ delete(table) {
155
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
156
+ this.sql = `DELETE FROM ${parsedTableName}`;
157
+ return this;
158
+ }
159
+ /**
160
+ * Create a table if it doesn't exist
161
+ * @param table The table name
162
+ * @param columnDefinitions The column definitions as an array of strings
163
+ * @param tableConstraints Optional constraints for the table
164
+ * @returns The builder instance
165
+ */
166
+ createTable(table, columnDefinitions, tableConstraints) {
167
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
168
+ const columns = columnDefinitions.map((def) => {
169
+ const colName = def.split(/\s+/)[0];
170
+ if (!colName) throw new Error("Empty column name in definition");
171
+ (0, _mastra_core_utils.parseSqlIdentifier)(colName, "column name");
172
+ return def;
173
+ }).join(", ");
174
+ const constraints = tableConstraints && tableConstraints.length > 0 ? ", " + tableConstraints.join(", ") : "";
175
+ this.sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns}${constraints})`;
176
+ return this;
177
+ }
178
+ /**
179
+ * Check if an index exists in the database
180
+ * @param indexName The name of the index to check
181
+ * @param tableName The table the index is on
182
+ * @returns The builder instance
183
+ */
184
+ checkIndexExists(indexName, tableName) {
185
+ this.sql = `SELECT name FROM sqlite_master WHERE type='index' AND name=? AND tbl_name=?`;
186
+ this.params.push(indexName, tableName);
187
+ return this;
188
+ }
189
+ /**
190
+ * Create an index if it doesn't exist
191
+ * @param indexName The name of the index to create
192
+ * @param tableName The table to create the index on
193
+ * @param columnName The column to index
194
+ * @param indexType Optional index type (e.g., 'UNIQUE')
195
+ * @returns The builder instance
196
+ */
197
+ createIndex(indexName, tableName, columnName, indexType = "") {
198
+ const parsedIndexName = (0, _mastra_core_utils.parseSqlIdentifier)(indexName, "index name");
199
+ const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(tableName, "table name");
200
+ const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(columnName, "column name");
201
+ this.sql = `CREATE ${indexType ? indexType + " " : ""}INDEX IF NOT EXISTS ${parsedIndexName} ON ${parsedTableName}(${parsedColumnName})`;
202
+ return this;
203
+ }
204
+ /**
205
+ * Add a LIKE condition to the query
206
+ * @param column The column to check
207
+ * @param value The value to match (will be wrapped with % for LIKE)
208
+ * @param exact If true, will not add % wildcards
209
+ */
210
+ like(column, value, exact = false) {
211
+ const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
212
+ const likeValue = exact ? value : `%${value}%`;
213
+ if (this.whereAdded) this.sql += ` AND ${parsedColumnName} LIKE ?`;
214
+ else {
215
+ this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
216
+ this.whereAdded = true;
217
+ }
218
+ this.params.push(likeValue);
219
+ return this;
220
+ }
221
+ /**
222
+ * Add a JSON LIKE condition for searching in JSON fields
223
+ * @param column The JSON column to search in
224
+ * @param key The JSON key to match
225
+ * @param value The value to match
226
+ */
227
+ jsonLike(column, key, value) {
228
+ const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
229
+ const jsonPattern = `%"${(0, _mastra_core_utils.parseSqlIdentifier)(key, "key name")}":"${value}"%`;
230
+ if (this.whereAdded) this.sql += ` AND ${parsedColumnName} LIKE ?`;
231
+ else {
232
+ this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
233
+ this.whereAdded = true;
234
+ }
235
+ this.params.push(jsonPattern);
236
+ return this;
237
+ }
238
+ /**
239
+ * Get the built query
240
+ * @returns Object containing the SQL string and parameters array
241
+ */
242
+ build() {
243
+ return {
244
+ sql: this.sql,
245
+ params: this.params
246
+ };
247
+ }
248
+ /**
249
+ * Reset the builder for reuse
250
+ * @returns The reset builder instance
251
+ */
252
+ reset() {
253
+ this.sql = "";
254
+ this.params = [];
255
+ this.whereAdded = false;
256
+ return this;
257
+ }
248
258
  };
249
259
  function createSqlBuilder() {
250
- return new SqlBuilder();
260
+ return new SqlBuilder();
251
261
  }
252
- var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z0-9_]+(\s+AS\s+[a-zA-Z0-9_]+)?$/;
262
+ const SQL_IDENTIFIER_PATTERN = /^[a-zA-Z0-9_]+(\s+AS\s+[a-zA-Z0-9_]+)?$/;
263
+ /**
264
+ * Parses and returns a valid SQL SELECT column identifier.
265
+ * Allows a single identifier (letters, numbers, underscores), or '*', optionally with 'AS alias'.
266
+ *
267
+ * @param column - The column identifier string to parse.
268
+ * @returns The validated column identifier as a branded type.
269
+ * @throws {Error} If invalid.
270
+ *
271
+ * @example
272
+ * const col = parseSelectIdentifier('user_id'); // Ok
273
+ * parseSelectIdentifier('user_id AS uid'); // Ok
274
+ * parseSelectIdentifier('*'); // Ok
275
+ * parseSelectIdentifier('user id'); // Throws error
276
+ */
253
277
  function parseSelectIdentifier(column) {
254
- if (column !== "*" && !SQL_IDENTIFIER_PATTERN.test(column)) {
255
- throw new Error(
256
- `Invalid column name: "${column}". Must be "*" or a valid identifier (letters, numbers, underscores), optionally with "AS alias".`
257
- );
258
- }
259
- return column;
278
+ if (column !== "*" && !SQL_IDENTIFIER_PATTERN.test(column)) throw new Error(`Invalid column name: "${column}". Must be "*" or a valid identifier (letters, numbers, underscores), optionally with "AS alias".`);
279
+ return column;
260
280
  }
261
-
262
- // src/storage/db/index.ts
281
+ //#endregion
282
+ //#region src/storage/db/index.ts
283
+ /**
284
+ * Resolves D1DomainConfig to D1DBConfig.
285
+ * Handles creating a new D1 client if apiToken is provided.
286
+ */
263
287
  function resolveD1Config(config) {
264
- if ("client" in config) {
265
- return {
266
- client: config.client,
267
- tablePrefix: config.tablePrefix
268
- };
269
- }
270
- if ("binding" in config) {
271
- return {
272
- binding: config.binding,
273
- tablePrefix: config.tablePrefix
274
- };
275
- }
276
- const cfClient = new Cloudflare__default.default({ apiToken: config.apiToken });
277
- return {
278
- client: {
279
- query: ({ sql, params }) => {
280
- return cfClient.d1.database.query(config.databaseId, {
281
- account_id: config.accountId,
282
- sql,
283
- params
284
- });
285
- }
286
- },
287
- tablePrefix: config.tablePrefix
288
- };
288
+ if ("client" in config) return {
289
+ client: config.client,
290
+ tablePrefix: config.tablePrefix
291
+ };
292
+ if ("binding" in config) return {
293
+ binding: config.binding,
294
+ tablePrefix: config.tablePrefix
295
+ };
296
+ const cfClient = new cloudflare.default({ apiToken: config.apiToken });
297
+ return {
298
+ client: { query: ({ sql, params }) => {
299
+ return cfClient.d1.database.query(config.databaseId, {
300
+ account_id: config.accountId,
301
+ sql,
302
+ params
303
+ });
304
+ } },
305
+ tablePrefix: config.tablePrefix
306
+ };
289
307
  }
290
- var D1DB = class extends base.MastraBase {
291
- client;
292
- binding;
293
- tablePrefix;
294
- /** Cache of actual table columns: tableName -> Promise<Set<columnName>> (stores in-flight promise to coalesce concurrent calls) */
295
- tableColumnsCache = /* @__PURE__ */ new Map();
296
- constructor(config) {
297
- super({
298
- component: "STORAGE",
299
- name: "D1_DB"
300
- });
301
- this.client = config.client;
302
- this.binding = config.binding;
303
- this.tablePrefix = config.tablePrefix || "";
304
- }
305
- async hasColumn(table, column) {
306
- const fullTableName = table.startsWith(this.tablePrefix) ? table : `${this.tablePrefix}${table}`;
307
- const sql = `PRAGMA table_info(${fullTableName});`;
308
- const result = await this.executeQuery({ sql, params: [] });
309
- if (!result || !Array.isArray(result)) return false;
310
- return result.some((col) => col.name === column || col.name === column.toLowerCase());
311
- }
312
- getTableName(tableName) {
313
- return `${this.tablePrefix}${tableName}`;
314
- }
315
- formatSqlParams(params) {
316
- return params.map((p) => p === void 0 || p === null ? null : p);
317
- }
318
- async executeWorkersBindingQuery({
319
- sql,
320
- params = [],
321
- first = false
322
- }) {
323
- if (!this.binding) {
324
- throw new Error("Workers binding is not configured");
325
- }
326
- try {
327
- const statement = this.binding.prepare(sql);
328
- const formattedParams = this.formatSqlParams(params);
329
- let result;
330
- if (formattedParams.length > 0) {
331
- if (first) {
332
- result = await statement.bind(...formattedParams).first();
333
- if (!result) return null;
334
- return result;
335
- } else {
336
- result = await statement.bind(...formattedParams).all();
337
- const results = result.results || [];
338
- return results;
339
- }
340
- } else {
341
- if (first) {
342
- result = await statement.first();
343
- if (!result) return null;
344
- return result;
345
- } else {
346
- result = await statement.all();
347
- const results = result.results || [];
348
- return results;
349
- }
350
- }
351
- } catch (error$1) {
352
- throw new error.MastraError(
353
- {
354
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "WORKERS_BINDING_QUERY", "FAILED"),
355
- domain: error.ErrorDomain.STORAGE,
356
- category: error.ErrorCategory.THIRD_PARTY,
357
- details: { sql }
358
- },
359
- error$1
360
- );
361
- }
362
- }
363
- async executeRestQuery({
364
- sql,
365
- params = [],
366
- first = false
367
- }) {
368
- if (!this.client) {
369
- throw new Error("D1 client is not configured");
370
- }
371
- try {
372
- const formattedParams = this.formatSqlParams(params);
373
- const response = await this.client.query({
374
- sql,
375
- params: formattedParams
376
- });
377
- const result = response.result || [];
378
- const results = result.flatMap((r) => r.results || []);
379
- if (first) {
380
- return results[0] || null;
381
- }
382
- return results;
383
- } catch (error$1) {
384
- throw new error.MastraError(
385
- {
386
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "REST_QUERY", "FAILED"),
387
- domain: error.ErrorDomain.STORAGE,
388
- category: error.ErrorCategory.THIRD_PARTY,
389
- details: { sql }
390
- },
391
- error$1
392
- );
393
- }
394
- }
395
- async executeQuery(options) {
396
- if (this.binding) {
397
- return this.executeWorkersBindingQuery(options);
398
- } else if (this.client) {
399
- return this.executeRestQuery(options);
400
- } else {
401
- throw new Error("Neither binding nor client is configured");
402
- }
403
- }
404
- /**
405
- * Gets the set of column names that actually exist in the database table.
406
- * Results are cached; the cache is invalidated when alterTable() adds new columns.
407
- */
408
- async getKnownColumnNames(tableName) {
409
- const cached = this.tableColumnsCache.get(tableName);
410
- if (cached) return cached;
411
- const promise = this.getTableColumns(tableName).then((columns) => {
412
- const names = new Set(columns.map((c) => c.name));
413
- if (names.size === 0) {
414
- this.tableColumnsCache.delete(tableName);
415
- }
416
- return names;
417
- });
418
- this.tableColumnsCache.set(tableName, promise);
419
- return promise;
420
- }
421
- /**
422
- * Filters a record to only include columns that exist in the actual database table.
423
- * Unknown columns are silently dropped to ensure forward compatibility.
424
- */
425
- async filterRecordToKnownColumns(tableName, record) {
426
- const knownColumns = await this.getKnownColumnNames(tableName);
427
- if (knownColumns.size === 0) return record;
428
- const filtered = {};
429
- for (const [key, value] of Object.entries(record)) {
430
- if (knownColumns.has(key)) {
431
- filtered[key] = value;
432
- }
433
- }
434
- return filtered;
435
- }
436
- async getTableColumns(tableName) {
437
- try {
438
- const sql = `PRAGMA table_info(${tableName})`;
439
- const result = await this.executeQuery({ sql });
440
- if (!result || !Array.isArray(result)) {
441
- return [];
442
- }
443
- return result.map((row) => ({
444
- name: row.name,
445
- type: row.type
446
- }));
447
- } catch (error) {
448
- this.logger.warn(`Failed to get table columns for ${tableName}:`, error);
449
- return [];
450
- }
451
- }
452
- serializeValue(value) {
453
- if (value === null || value === void 0) {
454
- return null;
455
- }
456
- if (value instanceof Date) {
457
- return value.toISOString();
458
- }
459
- if (typeof value === "object") {
460
- return JSON.stringify(value);
461
- }
462
- return value;
463
- }
464
- getSqlType(type) {
465
- switch (type) {
466
- case "bigint":
467
- return "INTEGER";
468
- // SQLite uses INTEGER for all integer sizes
469
- case "jsonb":
470
- return "TEXT";
471
- // Store JSON as TEXT in SQLite
472
- case "boolean":
473
- return "INTEGER";
474
- // SQLite uses 0/1 for booleans
475
- default:
476
- return storage.getSqlType(type);
477
- }
478
- }
479
- getDefaultValue(type) {
480
- return storage.getDefaultValue(type);
481
- }
482
- async createTable({
483
- tableName,
484
- schema
485
- }) {
486
- try {
487
- const fullTableName = this.getTableName(tableName);
488
- const columnDefinitions = Object.entries(schema).map(([colName, colDef]) => {
489
- const type = this.getSqlType(colDef.type);
490
- const nullable = colDef.nullable === false ? "NOT NULL" : "";
491
- const primaryKey = colDef.primaryKey ? "PRIMARY KEY" : "";
492
- return `${colName} ${type} ${nullable} ${primaryKey}`.trim();
493
- });
494
- const tableConstraints = [];
495
- if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
496
- tableConstraints.push("UNIQUE (workflow_name, run_id)");
497
- }
498
- const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
499
- const { sql, params } = query.build();
500
- await this.executeQuery({ sql, params });
501
- this.logger.debug(`Created table ${fullTableName}`);
502
- this.tableColumnsCache.delete(fullTableName);
503
- } catch (error$1) {
504
- throw new error.MastraError(
505
- {
506
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "CREATE_TABLE", "FAILED"),
507
- domain: error.ErrorDomain.STORAGE,
508
- category: error.ErrorCategory.THIRD_PARTY,
509
- details: { tableName }
510
- },
511
- error$1
512
- );
513
- }
514
- }
515
- async clearTable({ tableName }) {
516
- try {
517
- const fullTableName = this.getTableName(tableName);
518
- const query = createSqlBuilder().delete(fullTableName);
519
- const { sql, params } = query.build();
520
- await this.executeQuery({ sql, params });
521
- this.logger.debug(`Cleared table ${fullTableName}`);
522
- } catch (error$1) {
523
- throw new error.MastraError(
524
- {
525
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "CLEAR_TABLE", "FAILED"),
526
- domain: error.ErrorDomain.STORAGE,
527
- category: error.ErrorCategory.THIRD_PARTY,
528
- details: { tableName }
529
- },
530
- error$1
531
- );
532
- }
533
- }
534
- async dropTable({ tableName }) {
535
- const fullTableName = this.getTableName(tableName);
536
- try {
537
- const sql = `DROP TABLE IF EXISTS ${fullTableName}`;
538
- await this.executeQuery({ sql });
539
- this.logger.debug(`Dropped table ${fullTableName}`);
540
- } catch (error$1) {
541
- throw new error.MastraError(
542
- {
543
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "DROP_TABLE", "FAILED"),
544
- domain: error.ErrorDomain.STORAGE,
545
- category: error.ErrorCategory.THIRD_PARTY,
546
- details: { tableName }
547
- },
548
- error$1
549
- );
550
- } finally {
551
- this.tableColumnsCache.delete(fullTableName);
552
- }
553
- }
554
- async alterTable(args) {
555
- const fullTableName = this.getTableName(args.tableName);
556
- try {
557
- const existingColumns = await this.getTableColumns(fullTableName);
558
- const existingColumnNames = new Set(existingColumns.map((col) => col.name));
559
- for (const [columnName, column] of Object.entries(args.schema)) {
560
- if (!existingColumnNames.has(columnName) && args.ifNotExists.includes(columnName)) {
561
- const sqlType = this.getSqlType(column.type);
562
- const defaultValue = this.getDefaultValue(column.type);
563
- const sql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${sqlType} ${defaultValue}`;
564
- await this.executeQuery({ sql });
565
- this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
566
- }
567
- }
568
- } catch (error$1) {
569
- throw new error.MastraError(
570
- {
571
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "ALTER_TABLE", "FAILED"),
572
- domain: error.ErrorDomain.STORAGE,
573
- category: error.ErrorCategory.THIRD_PARTY,
574
- details: { tableName: args.tableName }
575
- },
576
- error$1
577
- );
578
- } finally {
579
- this.tableColumnsCache.delete(fullTableName);
580
- }
581
- }
582
- async insert({ tableName, record }) {
583
- try {
584
- const fullTableName = this.getTableName(tableName);
585
- const processedRecord = await this.processRecord(record);
586
- const filteredRecord = await this.filterRecordToKnownColumns(fullTableName, processedRecord);
587
- const columns = Object.keys(filteredRecord);
588
- if (columns.length === 0) return;
589
- const values = Object.values(filteredRecord);
590
- const query = createSqlBuilder().insert(fullTableName, columns, values);
591
- const { sql, params } = query.build();
592
- await this.executeQuery({ sql, params });
593
- } catch (error$1) {
594
- throw new error.MastraError(
595
- {
596
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "INSERT", "FAILED"),
597
- domain: error.ErrorDomain.STORAGE,
598
- category: error.ErrorCategory.THIRD_PARTY,
599
- details: { tableName }
600
- },
601
- error$1
602
- );
603
- }
604
- }
605
- async batchInsert({ tableName, records }) {
606
- try {
607
- if (records.length === 0) return;
608
- const fullTableName = this.getTableName(tableName);
609
- const processedRecords = await Promise.all(records.map((record) => this.processRecord(record)));
610
- const filteredRecords = await Promise.all(
611
- processedRecords.map((r) => this.filterRecordToKnownColumns(fullTableName, r))
612
- );
613
- for (const record of filteredRecords) {
614
- const columns = Object.keys(record);
615
- if (columns.length === 0) continue;
616
- const values = Object.values(record);
617
- const query = createSqlBuilder().insert(fullTableName, columns, values);
618
- const { sql, params } = query.build();
619
- await this.executeQuery({ sql, params });
620
- }
621
- } catch (error$1) {
622
- throw new error.MastraError(
623
- {
624
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "BATCH_INSERT", "FAILED"),
625
- domain: error.ErrorDomain.STORAGE,
626
- category: error.ErrorCategory.THIRD_PARTY,
627
- details: { tableName }
628
- },
629
- error$1
630
- );
631
- }
632
- }
633
- async load({ tableName, keys }) {
634
- try {
635
- const fullTableName = this.getTableName(tableName);
636
- const query = createSqlBuilder().select("*").from(fullTableName);
637
- let firstKey = true;
638
- for (const [key, value] of Object.entries(keys)) {
639
- if (firstKey) {
640
- query.where(`${key} = ?`, value);
641
- firstKey = false;
642
- } else {
643
- query.andWhere(`${key} = ?`, value);
644
- }
645
- }
646
- query.orderBy("createdAt", "DESC");
647
- query.limit(1);
648
- const { sql, params } = query.build();
649
- const result = await this.executeQuery({ sql, params, first: true });
650
- if (!result) {
651
- return null;
652
- }
653
- const deserializedResult = {};
654
- for (const [key, value] of Object.entries(result)) {
655
- deserializedResult[key] = deserializeValue(value);
656
- }
657
- return deserializedResult;
658
- } catch (error$1) {
659
- throw new error.MastraError(
660
- {
661
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LOAD", "FAILED"),
662
- domain: error.ErrorDomain.STORAGE,
663
- category: error.ErrorCategory.THIRD_PARTY,
664
- details: { tableName }
665
- },
666
- error$1
667
- );
668
- }
669
- }
670
- async processRecord(record) {
671
- const processed = {};
672
- for (const [key, value] of Object.entries(record)) {
673
- processed[key] = this.serializeValue(value);
674
- }
675
- return processed;
676
- }
677
- /**
678
- * Upsert multiple records in a batch operation
679
- * @param tableName The table to insert into
680
- * @param records The records to insert
681
- */
682
- async batchUpsert({ tableName, records }) {
683
- if (records.length === 0) return;
684
- const fullTableName = this.getTableName(tableName);
685
- try {
686
- const batchSize = 50;
687
- for (let i = 0; i < records.length; i += batchSize) {
688
- const batch = records.slice(i, i + batchSize);
689
- const recordsToInsert = batch;
690
- if (recordsToInsert.length > 0) {
691
- const filteredRecords = await Promise.all(
692
- recordsToInsert.map((r) => this.filterRecordToKnownColumns(fullTableName, r || {}))
693
- );
694
- for (const record of filteredRecords) {
695
- const columns = Object.keys(record);
696
- if (columns.length === 0) continue;
697
- const values = columns.map((col) => {
698
- const value = record[col];
699
- return this.serializeValue(value);
700
- });
701
- const recordToUpsert = columns.reduce(
702
- (acc, col) => {
703
- if (col !== "createdAt") acc[col] = `excluded.${col}`;
704
- return acc;
705
- },
706
- {}
707
- );
708
- const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert);
709
- const { sql, params } = query.build();
710
- await this.executeQuery({ sql, params });
711
- }
712
- }
713
- this.logger.debug(
714
- `Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`
715
- );
716
- }
717
- this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
718
- } catch (error$1) {
719
- throw new error.MastraError(
720
- {
721
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "BATCH_UPSERT", "FAILED"),
722
- domain: error.ErrorDomain.STORAGE,
723
- category: error.ErrorCategory.THIRD_PARTY,
724
- text: `Failed to batch upsert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
725
- details: { tableName }
726
- },
727
- error$1
728
- );
729
- }
730
- }
308
+ var D1DB = class extends _mastra_core_base.MastraBase {
309
+ client;
310
+ binding;
311
+ tablePrefix;
312
+ /** Cache of actual table columns: tableName -> Promise<Set<columnName>> (stores in-flight promise to coalesce concurrent calls) */
313
+ tableColumnsCache = /* @__PURE__ */ new Map();
314
+ constructor(config) {
315
+ super({
316
+ component: "STORAGE",
317
+ name: "D1_DB"
318
+ });
319
+ this.client = config.client;
320
+ this.binding = config.binding;
321
+ this.tablePrefix = config.tablePrefix || "";
322
+ }
323
+ async hasColumn(table, column) {
324
+ const sql = `PRAGMA table_info(${table.startsWith(this.tablePrefix) ? table : `${this.tablePrefix}${table}`});`;
325
+ const result = await this.executeQuery({
326
+ sql,
327
+ params: []
328
+ });
329
+ if (!result || !Array.isArray(result)) return false;
330
+ return result.some((col) => col.name === column || col.name === column.toLowerCase());
331
+ }
332
+ getTableName(tableName) {
333
+ return `${this.tablePrefix}${tableName}`;
334
+ }
335
+ formatSqlParams(params) {
336
+ return params.map((p) => p === void 0 || p === null ? null : p);
337
+ }
338
+ async executeWorkersBindingQuery({ sql, params = [], first = false }) {
339
+ if (!this.binding) throw new Error("Workers binding is not configured");
340
+ try {
341
+ const statement = this.binding.prepare(sql);
342
+ const formattedParams = this.formatSqlParams(params);
343
+ let result;
344
+ if (formattedParams.length > 0) if (first) {
345
+ result = await statement.bind(...formattedParams).first();
346
+ if (!result) return null;
347
+ return result;
348
+ } else {
349
+ result = await statement.bind(...formattedParams).all();
350
+ return result.results || [];
351
+ }
352
+ else if (first) {
353
+ result = await statement.first();
354
+ if (!result) return null;
355
+ return result;
356
+ } else {
357
+ result = await statement.all();
358
+ return result.results || [];
359
+ }
360
+ } catch (error) {
361
+ throw new _mastra_core_error.MastraError({
362
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "WORKERS_BINDING_QUERY", "FAILED"),
363
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
364
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
365
+ details: { sql }
366
+ }, error);
367
+ }
368
+ }
369
+ async executeRestQuery({ sql, params = [], first = false }) {
370
+ if (!this.client) throw new Error("D1 client is not configured");
371
+ try {
372
+ const formattedParams = this.formatSqlParams(params);
373
+ const results = ((await this.client.query({
374
+ sql,
375
+ params: formattedParams
376
+ })).result || []).flatMap((r) => r.results || []);
377
+ if (first) return results[0] || null;
378
+ return results;
379
+ } catch (error) {
380
+ throw new _mastra_core_error.MastraError({
381
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "REST_QUERY", "FAILED"),
382
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
383
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
384
+ details: { sql }
385
+ }, error);
386
+ }
387
+ }
388
+ async executeQuery(options) {
389
+ if (this.binding) return this.executeWorkersBindingQuery(options);
390
+ else if (this.client) return this.executeRestQuery(options);
391
+ else throw new Error("Neither binding nor client is configured");
392
+ }
393
+ /**
394
+ * Gets the set of column names that actually exist in the database table.
395
+ * Results are cached; the cache is invalidated when alterTable() adds new columns.
396
+ */
397
+ async getKnownColumnNames(tableName) {
398
+ const cached = this.tableColumnsCache.get(tableName);
399
+ if (cached) return cached;
400
+ const promise = this.getTableColumns(tableName).then((columns) => {
401
+ const names = new Set(columns.map((c) => c.name));
402
+ if (names.size === 0) this.tableColumnsCache.delete(tableName);
403
+ return names;
404
+ });
405
+ this.tableColumnsCache.set(tableName, promise);
406
+ return promise;
407
+ }
408
+ /**
409
+ * Filters a record to only include columns that exist in the actual database table.
410
+ * Unknown columns are silently dropped to ensure forward compatibility.
411
+ */
412
+ async filterRecordToKnownColumns(tableName, record) {
413
+ const knownColumns = await this.getKnownColumnNames(tableName);
414
+ if (knownColumns.size === 0) return record;
415
+ const filtered = {};
416
+ for (const [key, value] of Object.entries(record)) if (knownColumns.has(key)) filtered[key] = value;
417
+ return filtered;
418
+ }
419
+ async getTableColumns(tableName) {
420
+ try {
421
+ const sql = `PRAGMA table_info(${tableName})`;
422
+ const result = await this.executeQuery({ sql });
423
+ if (!result || !Array.isArray(result)) return [];
424
+ return result.map((row) => ({
425
+ name: row.name,
426
+ type: row.type
427
+ }));
428
+ } catch (error) {
429
+ this.logger.warn(`Failed to get table columns for ${tableName}:`, error);
430
+ return [];
431
+ }
432
+ }
433
+ serializeValue(value) {
434
+ if (value === null || value === void 0) return null;
435
+ if (value instanceof Date) return value.toISOString();
436
+ if (typeof value === "object") return JSON.stringify(value);
437
+ return value;
438
+ }
439
+ getSqlType(type) {
440
+ switch (type) {
441
+ case "bigint": return "INTEGER";
442
+ case "jsonb": return "TEXT";
443
+ case "boolean": return "INTEGER";
444
+ default: return (0, _mastra_core_storage.getSqlType)(type);
445
+ }
446
+ }
447
+ getDefaultValue(type) {
448
+ return (0, _mastra_core_storage.getDefaultValue)(type);
449
+ }
450
+ async createTable({ tableName, schema }) {
451
+ try {
452
+ const fullTableName = this.getTableName(tableName);
453
+ const columnDefinitions = Object.entries(schema).map(([colName, colDef]) => {
454
+ return `${colName} ${this.getSqlType(colDef.type)} ${colDef.nullable === false ? "NOT NULL" : ""} ${colDef.primaryKey ? "PRIMARY KEY" : ""}`.trim();
455
+ });
456
+ const tableConstraints = [];
457
+ if (tableName === _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT) tableConstraints.push("UNIQUE (workflow_name, run_id)");
458
+ const { sql, params } = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints).build();
459
+ await this.executeQuery({
460
+ sql,
461
+ params
462
+ });
463
+ this.logger.debug(`Created table ${fullTableName}`);
464
+ this.tableColumnsCache.delete(fullTableName);
465
+ } catch (error) {
466
+ throw new _mastra_core_error.MastraError({
467
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "CREATE_TABLE", "FAILED"),
468
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
469
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
470
+ details: { tableName }
471
+ }, error);
472
+ }
473
+ }
474
+ async clearTable({ tableName }) {
475
+ try {
476
+ const fullTableName = this.getTableName(tableName);
477
+ const { sql, params } = createSqlBuilder().delete(fullTableName).build();
478
+ await this.executeQuery({
479
+ sql,
480
+ params
481
+ });
482
+ this.logger.debug(`Cleared table ${fullTableName}`);
483
+ } catch (error) {
484
+ throw new _mastra_core_error.MastraError({
485
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "CLEAR_TABLE", "FAILED"),
486
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
487
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
488
+ details: { tableName }
489
+ }, error);
490
+ }
491
+ }
492
+ async dropTable({ tableName }) {
493
+ const fullTableName = this.getTableName(tableName);
494
+ try {
495
+ const sql = `DROP TABLE IF EXISTS ${fullTableName}`;
496
+ await this.executeQuery({ sql });
497
+ this.logger.debug(`Dropped table ${fullTableName}`);
498
+ } catch (error) {
499
+ throw new _mastra_core_error.MastraError({
500
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DROP_TABLE", "FAILED"),
501
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
502
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
503
+ details: { tableName }
504
+ }, error);
505
+ } finally {
506
+ this.tableColumnsCache.delete(fullTableName);
507
+ }
508
+ }
509
+ async alterTable(args) {
510
+ const fullTableName = this.getTableName(args.tableName);
511
+ try {
512
+ const existingColumns = await this.getTableColumns(fullTableName);
513
+ const existingColumnNames = new Set(existingColumns.map((col) => col.name));
514
+ for (const [columnName, column] of Object.entries(args.schema)) if (!existingColumnNames.has(columnName) && args.ifNotExists.includes(columnName)) {
515
+ const sql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${this.getSqlType(column.type)} ${this.getDefaultValue(column.type)}`;
516
+ await this.executeQuery({ sql });
517
+ this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
518
+ }
519
+ } catch (error) {
520
+ throw new _mastra_core_error.MastraError({
521
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "ALTER_TABLE", "FAILED"),
522
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
523
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
524
+ details: { tableName: args.tableName }
525
+ }, error);
526
+ } finally {
527
+ this.tableColumnsCache.delete(fullTableName);
528
+ }
529
+ }
530
+ async insert({ tableName, record }) {
531
+ try {
532
+ const fullTableName = this.getTableName(tableName);
533
+ const processedRecord = await this.processRecord(record);
534
+ const filteredRecord = await this.filterRecordToKnownColumns(fullTableName, processedRecord);
535
+ const columns = Object.keys(filteredRecord);
536
+ if (columns.length === 0) return;
537
+ const values = Object.values(filteredRecord);
538
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
539
+ await this.executeQuery({
540
+ sql,
541
+ params
542
+ });
543
+ } catch (error) {
544
+ throw new _mastra_core_error.MastraError({
545
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "INSERT", "FAILED"),
546
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
547
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
548
+ details: { tableName }
549
+ }, error);
550
+ }
551
+ }
552
+ async batchInsert({ tableName, records }) {
553
+ try {
554
+ if (records.length === 0) return;
555
+ const fullTableName = this.getTableName(tableName);
556
+ const processedRecords = await Promise.all(records.map((record) => this.processRecord(record)));
557
+ const filteredRecords = await Promise.all(processedRecords.map((r) => this.filterRecordToKnownColumns(fullTableName, r)));
558
+ for (const record of filteredRecords) {
559
+ const columns = Object.keys(record);
560
+ if (columns.length === 0) continue;
561
+ const values = Object.values(record);
562
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
563
+ await this.executeQuery({
564
+ sql,
565
+ params
566
+ });
567
+ }
568
+ } catch (error) {
569
+ throw new _mastra_core_error.MastraError({
570
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "BATCH_INSERT", "FAILED"),
571
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
572
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
573
+ details: { tableName }
574
+ }, error);
575
+ }
576
+ }
577
+ async load({ tableName, keys }) {
578
+ try {
579
+ const fullTableName = this.getTableName(tableName);
580
+ const query = createSqlBuilder().select("*").from(fullTableName);
581
+ let firstKey = true;
582
+ for (const [key, value] of Object.entries(keys)) if (firstKey) {
583
+ query.where(`${key} = ?`, value);
584
+ firstKey = false;
585
+ } else query.andWhere(`${key} = ?`, value);
586
+ query.orderBy("createdAt", "DESC");
587
+ query.limit(1);
588
+ const { sql, params } = query.build();
589
+ const result = await this.executeQuery({
590
+ sql,
591
+ params,
592
+ first: true
593
+ });
594
+ if (!result) return null;
595
+ const deserializedResult = {};
596
+ for (const [key, value] of Object.entries(result)) deserializedResult[key] = deserializeValue(value);
597
+ return deserializedResult;
598
+ } catch (error) {
599
+ throw new _mastra_core_error.MastraError({
600
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LOAD", "FAILED"),
601
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
602
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
603
+ details: { tableName }
604
+ }, error);
605
+ }
606
+ }
607
+ async processRecord(record) {
608
+ const processed = {};
609
+ for (const [key, value] of Object.entries(record)) processed[key] = this.serializeValue(value);
610
+ return processed;
611
+ }
612
+ /**
613
+ * Upsert multiple records in a batch operation
614
+ * @param tableName The table to insert into
615
+ * @param records The records to insert
616
+ */
617
+ async batchUpsert({ tableName, records }) {
618
+ if (records.length === 0) return;
619
+ const fullTableName = this.getTableName(tableName);
620
+ try {
621
+ const batchSize = 50;
622
+ for (let i = 0; i < records.length; i += batchSize) {
623
+ const recordsToInsert = records.slice(i, i + batchSize);
624
+ if (recordsToInsert.length > 0) {
625
+ const filteredRecords = await Promise.all(recordsToInsert.map((r) => this.filterRecordToKnownColumns(fullTableName, r || {})));
626
+ for (const record of filteredRecords) {
627
+ const columns = Object.keys(record);
628
+ if (columns.length === 0) continue;
629
+ const values = columns.map((col) => {
630
+ const value = record[col];
631
+ return this.serializeValue(value);
632
+ });
633
+ const recordToUpsert = columns.reduce((acc, col) => {
634
+ if (col !== "createdAt") acc[col] = `excluded.${col}`;
635
+ return acc;
636
+ }, {});
637
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert).build();
638
+ await this.executeQuery({
639
+ sql,
640
+ params
641
+ });
642
+ }
643
+ }
644
+ this.logger.debug(`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`);
645
+ }
646
+ this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
647
+ } catch (error) {
648
+ throw new _mastra_core_error.MastraError({
649
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "BATCH_UPSERT", "FAILED"),
650
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
651
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
652
+ text: `Failed to batch upsert into ${tableName}: ${error instanceof Error ? error.message : String(error)}`,
653
+ details: { tableName }
654
+ }, error);
655
+ }
656
+ }
731
657
  };
732
-
733
- // src/storage/domains/background-tasks/index.ts
658
+ //#endregion
659
+ //#region src/storage/domains/background-tasks/index.ts
734
660
  function serializeJson(v) {
735
- if (typeof v === "object" && v != null) return JSON.stringify(v);
736
- return v ?? null;
661
+ if (typeof v === "object" && v != null) return JSON.stringify(v);
662
+ return v ?? null;
737
663
  }
738
664
  function rowToTask(row) {
739
- const parseJson = (val) => {
740
- if (val == null || val === "") return void 0;
741
- if (typeof val === "string") {
742
- try {
743
- return JSON.parse(val);
744
- } catch {
745
- return val;
746
- }
747
- }
748
- return val;
749
- };
750
- return {
751
- id: row.id,
752
- status: row.status,
753
- toolName: row.tool_name,
754
- toolCallId: row.tool_call_id,
755
- args: parseJson(row.args) ?? {},
756
- agentId: row.agent_id,
757
- threadId: row.thread_id || void 0,
758
- resourceId: row.resource_id || void 0,
759
- runId: row.run_id ?? "",
760
- result: parseJson(row.result),
761
- error: parseJson(row.error),
762
- suspendPayload: parseJson(row.suspend_payload),
763
- retryCount: Number(row.retry_count ?? 0),
764
- maxRetries: Number(row.max_retries ?? 0),
765
- timeoutMs: Number(row.timeout_ms ?? 3e5),
766
- createdAt: new Date(row.createdAt),
767
- startedAt: row.startedAt ? new Date(row.startedAt) : void 0,
768
- suspendedAt: row.suspendedAt ? new Date(row.suspendedAt) : void 0,
769
- completedAt: row.completedAt ? new Date(row.completedAt) : void 0
770
- };
665
+ const parseJson = (val) => {
666
+ if (val == null || val === "") return void 0;
667
+ if (typeof val === "string") try {
668
+ return JSON.parse(val);
669
+ } catch {
670
+ return val;
671
+ }
672
+ return val;
673
+ };
674
+ return {
675
+ id: row.id,
676
+ status: row.status,
677
+ toolName: row.tool_name,
678
+ toolCallId: row.tool_call_id,
679
+ args: parseJson(row.args) ?? {},
680
+ agentId: row.agent_id,
681
+ threadId: row.thread_id || void 0,
682
+ resourceId: row.resource_id || void 0,
683
+ runId: row.run_id ?? "",
684
+ result: parseJson(row.result),
685
+ error: parseJson(row.error),
686
+ suspendPayload: parseJson(row.suspend_payload),
687
+ retryCount: Number(row.retry_count ?? 0),
688
+ maxRetries: Number(row.max_retries ?? 0),
689
+ timeoutMs: Number(row.timeout_ms ?? 3e5),
690
+ createdAt: new Date(row.createdAt),
691
+ startedAt: row.startedAt ? new Date(row.startedAt) : void 0,
692
+ suspendedAt: row.suspendedAt ? new Date(row.suspendedAt) : void 0,
693
+ completedAt: row.completedAt ? new Date(row.completedAt) : void 0
694
+ };
771
695
  }
772
- var BackgroundTasksStorageD1 = class extends storage.BackgroundTasksStorage {
773
- #db;
774
- constructor(config) {
775
- super();
776
- const resolved = resolveD1Config(config);
777
- this.#db = new D1DB(resolved);
778
- }
779
- async init() {
780
- await this.#db.createTable({ tableName: storage.TABLE_BACKGROUND_TASKS, schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS] });
781
- await this.#db.alterTable({
782
- tableName: storage.TABLE_BACKGROUND_TASKS,
783
- schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS],
784
- ifNotExists: ["suspend_payload", "suspendedAt"]
785
- });
786
- }
787
- async dangerouslyClearAll() {
788
- await this.#db.clearTable({ tableName: storage.TABLE_BACKGROUND_TASKS });
789
- }
790
- async createTask(task) {
791
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
792
- const { sql, params } = createSqlBuilder().insert(
793
- fullTableName,
794
- [
795
- "id",
796
- "tool_call_id",
797
- "tool_name",
798
- "agent_id",
799
- "thread_id",
800
- "resource_id",
801
- "run_id",
802
- "status",
803
- "args",
804
- "result",
805
- "error",
806
- "suspend_payload",
807
- "retry_count",
808
- "max_retries",
809
- "timeout_ms",
810
- "createdAt",
811
- "startedAt",
812
- "suspendedAt",
813
- "completedAt"
814
- ],
815
- [
816
- task.id,
817
- task.toolCallId,
818
- task.toolName,
819
- task.agentId,
820
- task.threadId ?? null,
821
- task.resourceId ?? null,
822
- task.runId,
823
- task.status,
824
- serializeJson(task.args),
825
- serializeJson(task.result),
826
- serializeJson(task.error),
827
- serializeJson(task.suspendPayload),
828
- task.retryCount,
829
- task.maxRetries,
830
- task.timeoutMs,
831
- task.createdAt.toISOString(),
832
- task.startedAt?.toISOString() ?? null,
833
- task.suspendedAt?.toISOString() ?? null,
834
- task.completedAt?.toISOString() ?? null
835
- ]
836
- ).build();
837
- await this.#db.executeQuery({ sql, params });
838
- }
839
- async updateTask(taskId, update) {
840
- const sets = [];
841
- const params = [];
842
- if ("status" in update) {
843
- sets.push("status = ?");
844
- params.push(update.status);
845
- }
846
- if ("result" in update) {
847
- sets.push("result = ?");
848
- params.push(serializeJson(update.result));
849
- }
850
- if ("error" in update) {
851
- sets.push("error = ?");
852
- params.push(serializeJson(update.error));
853
- }
854
- if ("suspendPayload" in update) {
855
- sets.push("suspend_payload = ?");
856
- params.push(serializeJson(update.suspendPayload));
857
- }
858
- if ("retryCount" in update) {
859
- sets.push("retry_count = ?");
860
- params.push(update.retryCount);
861
- }
862
- if ("startedAt" in update) {
863
- sets.push("startedAt = ?");
864
- params.push(update.startedAt?.toISOString() ?? null);
865
- }
866
- if ("suspendedAt" in update) {
867
- sets.push("suspendedAt = ?");
868
- params.push(update.suspendedAt?.toISOString() ?? null);
869
- }
870
- if ("completedAt" in update) {
871
- sets.push("completedAt = ?");
872
- params.push(update.completedAt?.toISOString() ?? null);
873
- }
874
- if (sets.length === 0) return;
875
- params.push(taskId);
876
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
877
- await this.#db.executeQuery({
878
- sql: `UPDATE ${fullTableName} SET ${sets.join(", ")} WHERE id = ?`,
879
- params
880
- });
881
- }
882
- async getTask(taskId) {
883
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
884
- const { sql, params } = createSqlBuilder().select("*").from(fullTableName).where("id = ?", taskId).build();
885
- const row = await this.#db.executeQuery({ sql, params, first: true });
886
- return row ? rowToTask(row) : null;
887
- }
888
- async listTasks(filter) {
889
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
890
- let builder = createSqlBuilder().select("*").from(fullTableName);
891
- let countBuilder = createSqlBuilder().count().from(fullTableName);
892
- if (filter.status) {
893
- const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
894
- builder = builder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
895
- countBuilder = countBuilder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
896
- }
897
- if (filter.agentId) {
898
- builder = builder.whereAnd("agent_id = ?", filter.agentId);
899
- countBuilder = countBuilder.whereAnd("agent_id = ?", filter.agentId);
900
- }
901
- if (filter.threadId) {
902
- builder = builder.whereAnd("thread_id = ?", filter.threadId);
903
- countBuilder = countBuilder.whereAnd("thread_id = ?", filter.threadId);
904
- }
905
- if (filter.runId) {
906
- builder = builder.whereAnd("run_id = ?", filter.runId);
907
- countBuilder = countBuilder.whereAnd("run_id = ?", filter.runId);
908
- }
909
- if (filter.toolName) {
910
- builder = builder.whereAnd("tool_name = ?", filter.toolName);
911
- countBuilder = countBuilder.whereAnd("tool_name = ?", filter.toolName);
912
- }
913
- if (filter.toolCallId) {
914
- builder = builder.whereAnd("tool_call_id = ?", filter.toolCallId);
915
- countBuilder = countBuilder.whereAnd("tool_call_id = ?", filter.toolCallId);
916
- }
917
- const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
918
- if (filter.fromDate) {
919
- builder = builder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
920
- countBuilder = countBuilder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
921
- }
922
- if (filter.toDate) {
923
- builder = builder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
924
- countBuilder = countBuilder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
925
- }
926
- const { sql: countSql, params: countParams } = countBuilder.build();
927
- const countRow = await this.#db.executeQuery({ sql: countSql, params: countParams, first: true });
928
- const total = Number(countRow?.count ?? 0);
929
- const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "suspendedAt" ? "suspendedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
930
- builder = builder.orderBy(orderCol, filter.orderDirection === "desc" ? "DESC" : "ASC");
931
- if (filter.perPage != null) {
932
- builder = builder.limit(filter.perPage);
933
- if (filter.page != null) {
934
- builder = builder.offset(filter.page * filter.perPage);
935
- }
936
- }
937
- const { sql, params } = builder.build();
938
- const rows = await this.#db.executeQuery({ sql, params });
939
- return { tasks: rows.map(rowToTask), total };
940
- }
941
- async deleteTask(taskId) {
942
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
943
- await this.#db.executeQuery({ sql: `DELETE FROM ${fullTableName} WHERE id = ?`, params: [taskId] });
944
- }
945
- async deleteTasks(filter) {
946
- const conditions = [];
947
- const params = [];
948
- if (filter.status) {
949
- const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
950
- conditions.push(`status IN (${statuses.map(() => "?").join(",")})`);
951
- params.push(...statuses);
952
- }
953
- const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
954
- if (filter.fromDate) {
955
- conditions.push(`${dateCol} >= ?`);
956
- params.push(filter.fromDate.toISOString());
957
- }
958
- if (filter.toDate) {
959
- conditions.push(`${dateCol} < ?`);
960
- params.push(filter.toDate.toISOString());
961
- }
962
- if (filter.agentId) {
963
- conditions.push("agent_id = ?");
964
- params.push(filter.agentId);
965
- }
966
- if (filter.runId) {
967
- conditions.push("run_id = ?");
968
- params.push(filter.runId);
969
- }
970
- if (filter.toolCallId) {
971
- conditions.push("tool_call_id = ?");
972
- params.push(filter.toolCallId);
973
- }
974
- if (conditions.length === 0) return;
975
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
976
- await this.#db.executeQuery({
977
- sql: `DELETE FROM ${fullTableName} WHERE ${conditions.join(" AND ")}`,
978
- params
979
- });
980
- }
981
- async getRunningCount() {
982
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
983
- const row = await this.#db.executeQuery({
984
- sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running'`,
985
- params: [],
986
- first: true
987
- });
988
- return Number(row?.count ?? 0);
989
- }
990
- async getRunningCountByAgent(agentId) {
991
- const fullTableName = this.#db.getTableName(storage.TABLE_BACKGROUND_TASKS);
992
- const row = await this.#db.executeQuery({
993
- sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running' AND agent_id = ?`,
994
- params: [agentId],
995
- first: true
996
- });
997
- return Number(row?.count ?? 0);
998
- }
696
+ var BackgroundTasksStorageD1 = class extends _mastra_core_storage.BackgroundTasksStorage {
697
+ #db;
698
+ constructor(config) {
699
+ super();
700
+ const resolved = resolveD1Config(config);
701
+ this.#db = new D1DB(resolved);
702
+ }
703
+ async init() {
704
+ await this.#db.createTable({
705
+ tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS,
706
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_BACKGROUND_TASKS]
707
+ });
708
+ await this.#db.alterTable({
709
+ tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS,
710
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_BACKGROUND_TASKS],
711
+ ifNotExists: ["suspend_payload", "suspendedAt"]
712
+ });
713
+ }
714
+ async dangerouslyClearAll() {
715
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS });
716
+ }
717
+ async createTask(task) {
718
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
719
+ const { sql, params } = createSqlBuilder().insert(fullTableName, [
720
+ "id",
721
+ "tool_call_id",
722
+ "tool_name",
723
+ "agent_id",
724
+ "thread_id",
725
+ "resource_id",
726
+ "run_id",
727
+ "status",
728
+ "args",
729
+ "result",
730
+ "error",
731
+ "suspend_payload",
732
+ "retry_count",
733
+ "max_retries",
734
+ "timeout_ms",
735
+ "createdAt",
736
+ "startedAt",
737
+ "suspendedAt",
738
+ "completedAt"
739
+ ], [
740
+ task.id,
741
+ task.toolCallId,
742
+ task.toolName,
743
+ task.agentId,
744
+ task.threadId ?? null,
745
+ task.resourceId ?? null,
746
+ task.runId,
747
+ task.status,
748
+ serializeJson(task.args),
749
+ serializeJson(task.result),
750
+ serializeJson(task.error),
751
+ serializeJson(task.suspendPayload),
752
+ task.retryCount,
753
+ task.maxRetries,
754
+ task.timeoutMs,
755
+ task.createdAt.toISOString(),
756
+ task.startedAt?.toISOString() ?? null,
757
+ task.suspendedAt?.toISOString() ?? null,
758
+ task.completedAt?.toISOString() ?? null
759
+ ]).build();
760
+ await this.#db.executeQuery({
761
+ sql,
762
+ params
763
+ });
764
+ }
765
+ async updateTask(taskId, update) {
766
+ const sets = [];
767
+ const params = [];
768
+ if ("status" in update) {
769
+ sets.push("status = ?");
770
+ params.push(update.status);
771
+ }
772
+ if ("result" in update) {
773
+ sets.push("result = ?");
774
+ params.push(serializeJson(update.result));
775
+ }
776
+ if ("error" in update) {
777
+ sets.push("error = ?");
778
+ params.push(serializeJson(update.error));
779
+ }
780
+ if ("suspendPayload" in update) {
781
+ sets.push("suspend_payload = ?");
782
+ params.push(serializeJson(update.suspendPayload));
783
+ }
784
+ if ("retryCount" in update) {
785
+ sets.push("retry_count = ?");
786
+ params.push(update.retryCount);
787
+ }
788
+ if ("startedAt" in update) {
789
+ sets.push("startedAt = ?");
790
+ params.push(update.startedAt?.toISOString() ?? null);
791
+ }
792
+ if ("suspendedAt" in update) {
793
+ sets.push("suspendedAt = ?");
794
+ params.push(update.suspendedAt?.toISOString() ?? null);
795
+ }
796
+ if ("completedAt" in update) {
797
+ sets.push("completedAt = ?");
798
+ params.push(update.completedAt?.toISOString() ?? null);
799
+ }
800
+ if (sets.length === 0) return;
801
+ params.push(taskId);
802
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
803
+ await this.#db.executeQuery({
804
+ sql: `UPDATE ${fullTableName} SET ${sets.join(", ")} WHERE id = ?`,
805
+ params
806
+ });
807
+ }
808
+ async getTask(taskId) {
809
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
810
+ const { sql, params } = createSqlBuilder().select("*").from(fullTableName).where("id = ?", taskId).build();
811
+ const row = await this.#db.executeQuery({
812
+ sql,
813
+ params,
814
+ first: true
815
+ });
816
+ return row ? rowToTask(row) : null;
817
+ }
818
+ async listTasks(filter) {
819
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
820
+ let builder = createSqlBuilder().select("*").from(fullTableName);
821
+ let countBuilder = createSqlBuilder().count().from(fullTableName);
822
+ if (filter.status) {
823
+ const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
824
+ builder = builder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
825
+ countBuilder = countBuilder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
826
+ }
827
+ if (filter.agentId) {
828
+ builder = builder.whereAnd("agent_id = ?", filter.agentId);
829
+ countBuilder = countBuilder.whereAnd("agent_id = ?", filter.agentId);
830
+ }
831
+ if (filter.threadId) {
832
+ builder = builder.whereAnd("thread_id = ?", filter.threadId);
833
+ countBuilder = countBuilder.whereAnd("thread_id = ?", filter.threadId);
834
+ }
835
+ if (filter.runId) {
836
+ builder = builder.whereAnd("run_id = ?", filter.runId);
837
+ countBuilder = countBuilder.whereAnd("run_id = ?", filter.runId);
838
+ }
839
+ if (filter.toolName) {
840
+ builder = builder.whereAnd("tool_name = ?", filter.toolName);
841
+ countBuilder = countBuilder.whereAnd("tool_name = ?", filter.toolName);
842
+ }
843
+ if (filter.toolCallId) {
844
+ builder = builder.whereAnd("tool_call_id = ?", filter.toolCallId);
845
+ countBuilder = countBuilder.whereAnd("tool_call_id = ?", filter.toolCallId);
846
+ }
847
+ const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
848
+ if (filter.fromDate) {
849
+ builder = builder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
850
+ countBuilder = countBuilder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
851
+ }
852
+ if (filter.toDate) {
853
+ builder = builder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
854
+ countBuilder = countBuilder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
855
+ }
856
+ const { sql: countSql, params: countParams } = countBuilder.build();
857
+ const countRow = await this.#db.executeQuery({
858
+ sql: countSql,
859
+ params: countParams,
860
+ first: true
861
+ });
862
+ const total = Number(countRow?.count ?? 0);
863
+ const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "suspendedAt" ? "suspendedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
864
+ builder = builder.orderBy(orderCol, filter.orderDirection === "desc" ? "DESC" : "ASC");
865
+ if (filter.perPage != null) {
866
+ builder = builder.limit(filter.perPage);
867
+ if (filter.page != null) builder = builder.offset(filter.page * filter.perPage);
868
+ }
869
+ const { sql, params } = builder.build();
870
+ return {
871
+ tasks: (await this.#db.executeQuery({
872
+ sql,
873
+ params
874
+ })).map(rowToTask),
875
+ total
876
+ };
877
+ }
878
+ async deleteTask(taskId) {
879
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
880
+ await this.#db.executeQuery({
881
+ sql: `DELETE FROM ${fullTableName} WHERE id = ?`,
882
+ params: [taskId]
883
+ });
884
+ }
885
+ async deleteTasks(filter) {
886
+ const conditions = [];
887
+ const params = [];
888
+ if (filter.status) {
889
+ const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
890
+ conditions.push(`status IN (${statuses.map(() => "?").join(",")})`);
891
+ params.push(...statuses);
892
+ }
893
+ const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
894
+ if (filter.fromDate) {
895
+ conditions.push(`${dateCol} >= ?`);
896
+ params.push(filter.fromDate.toISOString());
897
+ }
898
+ if (filter.toDate) {
899
+ conditions.push(`${dateCol} < ?`);
900
+ params.push(filter.toDate.toISOString());
901
+ }
902
+ if (filter.agentId) {
903
+ conditions.push("agent_id = ?");
904
+ params.push(filter.agentId);
905
+ }
906
+ if (filter.runId) {
907
+ conditions.push("run_id = ?");
908
+ params.push(filter.runId);
909
+ }
910
+ if (filter.toolCallId) {
911
+ conditions.push("tool_call_id = ?");
912
+ params.push(filter.toolCallId);
913
+ }
914
+ if (conditions.length === 0) return;
915
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
916
+ await this.#db.executeQuery({
917
+ sql: `DELETE FROM ${fullTableName} WHERE ${conditions.join(" AND ")}`,
918
+ params
919
+ });
920
+ }
921
+ async getRunningCount() {
922
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
923
+ const row = await this.#db.executeQuery({
924
+ sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running'`,
925
+ params: [],
926
+ first: true
927
+ });
928
+ return Number(row?.count ?? 0);
929
+ }
930
+ async getRunningCountByAgent(agentId) {
931
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
932
+ const row = await this.#db.executeQuery({
933
+ sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running' AND agent_id = ?`,
934
+ params: [agentId],
935
+ first: true
936
+ });
937
+ return Number(row?.count ?? 0);
938
+ }
999
939
  };
1000
- var MemoryStorageD1 = class extends storage.MemoryStorage {
1001
- #db;
1002
- constructor(config) {
1003
- super();
1004
- this.#db = new D1DB(resolveD1Config(config));
1005
- }
1006
- async init() {
1007
- await this.#db.createTable({ tableName: storage.TABLE_THREADS, schema: storage.TABLE_SCHEMAS[storage.TABLE_THREADS] });
1008
- await this.#db.createTable({ tableName: storage.TABLE_MESSAGES, schema: storage.TABLE_SCHEMAS[storage.TABLE_MESSAGES] });
1009
- await this.#db.createTable({ tableName: storage.TABLE_RESOURCES, schema: storage.TABLE_SCHEMAS[storage.TABLE_RESOURCES] });
1010
- await this.#db.alterTable({
1011
- tableName: storage.TABLE_MESSAGES,
1012
- schema: storage.TABLE_SCHEMAS[storage.TABLE_MESSAGES],
1013
- ifNotExists: ["resourceId"]
1014
- });
1015
- }
1016
- async dangerouslyClearAll() {
1017
- await this.#db.clearTable({ tableName: storage.TABLE_MESSAGES });
1018
- await this.#db.clearTable({ tableName: storage.TABLE_THREADS });
1019
- await this.#db.clearTable({ tableName: storage.TABLE_RESOURCES });
1020
- }
1021
- async getResourceById({ resourceId }) {
1022
- const resource = await this.#db.load({
1023
- tableName: storage.TABLE_RESOURCES,
1024
- keys: { id: resourceId }
1025
- });
1026
- if (!resource) return null;
1027
- try {
1028
- return {
1029
- ...resource,
1030
- createdAt: storage.ensureDate(resource.createdAt),
1031
- updatedAt: storage.ensureDate(resource.updatedAt),
1032
- metadata: typeof resource.metadata === "string" ? JSON.parse(resource.metadata || "{}") : resource.metadata
1033
- };
1034
- } catch (error$1) {
1035
- const mastraError = new error.MastraError(
1036
- {
1037
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_RESOURCE_BY_ID", "FAILED"),
1038
- domain: error.ErrorDomain.STORAGE,
1039
- category: error.ErrorCategory.THIRD_PARTY,
1040
- text: `Error processing resource ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1041
- details: { resourceId }
1042
- },
1043
- error$1
1044
- );
1045
- this.logger?.error(mastraError.toString());
1046
- this.logger?.trackException(mastraError);
1047
- return null;
1048
- }
1049
- }
1050
- async saveResource({ resource }) {
1051
- const fullTableName = this.#db.getTableName(storage.TABLE_RESOURCES);
1052
- const resourceToSave = {
1053
- id: resource.id,
1054
- workingMemory: resource.workingMemory,
1055
- metadata: resource.metadata ? JSON.stringify(resource.metadata) : null,
1056
- createdAt: resource.createdAt,
1057
- updatedAt: resource.updatedAt
1058
- };
1059
- const processedRecord = await this.#db.processRecord(resourceToSave);
1060
- const columns = Object.keys(processedRecord);
1061
- const values = Object.values(processedRecord);
1062
- const updateMap = {
1063
- workingMemory: "excluded.workingMemory",
1064
- metadata: "excluded.metadata",
1065
- createdAt: "excluded.createdAt",
1066
- updatedAt: "excluded.updatedAt"
1067
- };
1068
- const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], updateMap);
1069
- const { sql, params } = query.build();
1070
- try {
1071
- await this.#db.executeQuery({ sql, params });
1072
- return resource;
1073
- } catch (error$1) {
1074
- throw new error.MastraError(
1075
- {
1076
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "SAVE_RESOURCE", "FAILED"),
1077
- domain: error.ErrorDomain.STORAGE,
1078
- category: error.ErrorCategory.THIRD_PARTY,
1079
- text: `Failed to save resource to ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1080
- details: { resourceId: resource.id }
1081
- },
1082
- error$1
1083
- );
1084
- }
1085
- }
1086
- async updateResource({
1087
- resourceId,
1088
- workingMemory,
1089
- metadata
1090
- }) {
1091
- const existingResource = await this.getResourceById({ resourceId });
1092
- if (!existingResource) {
1093
- const newResource = {
1094
- id: resourceId,
1095
- workingMemory,
1096
- metadata: metadata || {},
1097
- createdAt: /* @__PURE__ */ new Date(),
1098
- updatedAt: /* @__PURE__ */ new Date()
1099
- };
1100
- return this.saveResource({ resource: newResource });
1101
- }
1102
- const updatedAt = /* @__PURE__ */ new Date();
1103
- const updatedResource = {
1104
- ...existingResource,
1105
- workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
1106
- metadata: {
1107
- ...existingResource.metadata,
1108
- ...metadata
1109
- },
1110
- updatedAt
1111
- };
1112
- const fullTableName = this.#db.getTableName(storage.TABLE_RESOURCES);
1113
- const columns = ["workingMemory", "metadata", "updatedAt"];
1114
- const values = [updatedResource.workingMemory, JSON.stringify(updatedResource.metadata), updatedAt.toISOString()];
1115
- const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", resourceId);
1116
- const { sql, params } = query.build();
1117
- try {
1118
- await this.#db.executeQuery({ sql, params });
1119
- return updatedResource;
1120
- } catch (error$1) {
1121
- throw new error.MastraError(
1122
- {
1123
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "UPDATE_RESOURCE", "FAILED"),
1124
- domain: error.ErrorDomain.STORAGE,
1125
- category: error.ErrorCategory.THIRD_PARTY,
1126
- text: `Failed to update resource ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1127
- details: { resourceId }
1128
- },
1129
- error$1
1130
- );
1131
- }
1132
- }
1133
- async getThreadById({
1134
- threadId,
1135
- resourceId
1136
- }) {
1137
- const thread = await this.#db.load({
1138
- tableName: storage.TABLE_THREADS,
1139
- keys: { id: threadId }
1140
- });
1141
- if (!thread || resourceId !== void 0 && thread.resourceId !== resourceId) return null;
1142
- try {
1143
- return {
1144
- ...thread,
1145
- createdAt: storage.ensureDate(thread.createdAt),
1146
- updatedAt: storage.ensureDate(thread.updatedAt),
1147
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
1148
- };
1149
- } catch (error$1) {
1150
- const mastraError = new error.MastraError(
1151
- {
1152
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_THREAD_BY_ID", "FAILED"),
1153
- domain: error.ErrorDomain.STORAGE,
1154
- category: error.ErrorCategory.THIRD_PARTY,
1155
- text: `Error processing thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1156
- details: { threadId }
1157
- },
1158
- error$1
1159
- );
1160
- this.logger?.error(mastraError.toString());
1161
- this.logger?.trackException(mastraError);
1162
- return null;
1163
- }
1164
- }
1165
- async listThreads(args) {
1166
- const { page = 0, perPage: perPageInput, orderBy, filter } = args;
1167
- try {
1168
- this.validatePaginationInput(page, perPageInput ?? 100);
1169
- } catch (error$1) {
1170
- throw new error.MastraError(
1171
- {
1172
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_PAGE"),
1173
- domain: error.ErrorDomain.STORAGE,
1174
- category: error.ErrorCategory.USER,
1175
- details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
1176
- },
1177
- error$1 instanceof Error ? error$1 : new Error("Invalid pagination parameters")
1178
- );
1179
- }
1180
- const perPage = storage.normalizePerPage(perPageInput, 100);
1181
- try {
1182
- this.validateMetadataKeys(filter?.metadata);
1183
- } catch (error$1) {
1184
- throw new error.MastraError(
1185
- {
1186
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_KEY"),
1187
- domain: error.ErrorDomain.STORAGE,
1188
- category: error.ErrorCategory.USER,
1189
- details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
1190
- },
1191
- error$1 instanceof Error ? error$1 : new Error("Invalid metadata key")
1192
- );
1193
- }
1194
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1195
- const { field, direction } = this.parseOrderBy(orderBy);
1196
- const fullTableName = this.#db.getTableName(storage.TABLE_THREADS);
1197
- const mapRowToStorageThreadType = (row) => ({
1198
- ...row,
1199
- createdAt: storage.ensureDate(row.createdAt),
1200
- updatedAt: storage.ensureDate(row.updatedAt),
1201
- metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
1202
- });
1203
- try {
1204
- let countQuery = createSqlBuilder().count().from(fullTableName);
1205
- let selectQuery = createSqlBuilder().select("*").from(fullTableName);
1206
- if (filter?.resourceId) {
1207
- countQuery = countQuery.whereAnd("resourceId = ?", filter.resourceId);
1208
- selectQuery = selectQuery.whereAnd("resourceId = ?", filter.resourceId);
1209
- }
1210
- if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
1211
- for (const [key, value] of Object.entries(filter.metadata)) {
1212
- if (value !== null && typeof value === "object") {
1213
- throw new error.MastraError(
1214
- {
1215
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_VALUE"),
1216
- domain: error.ErrorDomain.STORAGE,
1217
- category: error.ErrorCategory.USER,
1218
- text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${Array.isArray(value) ? "array" : "object"}`,
1219
- details: { key, valueType: Array.isArray(value) ? "array" : "object" }
1220
- },
1221
- new Error("Invalid metadata filter value type")
1222
- );
1223
- }
1224
- if (value === null) {
1225
- const condition = `json_extract(metadata, '$.${key}') IS NULL`;
1226
- countQuery = countQuery.whereAnd(condition);
1227
- selectQuery = selectQuery.whereAnd(condition);
1228
- } else {
1229
- const condition = `json_extract(metadata, '$.${key}') = ?`;
1230
- const filterValue = value;
1231
- countQuery = countQuery.whereAnd(condition, filterValue);
1232
- selectQuery = selectQuery.whereAnd(condition, filterValue);
1233
- }
1234
- }
1235
- }
1236
- const countResult = await this.#db.executeQuery(countQuery.build());
1237
- const total = Number(countResult?.[0]?.count ?? 0);
1238
- if (total === 0) {
1239
- return {
1240
- threads: [],
1241
- total: 0,
1242
- page,
1243
- perPage: perPageForResponse,
1244
- hasMore: false
1245
- };
1246
- }
1247
- const limitValue = perPageInput === false ? total : perPage;
1248
- selectQuery = selectQuery.orderBy(field, direction).limit(limitValue).offset(offset);
1249
- const results = await this.#db.executeQuery(selectQuery.build());
1250
- const threads = results.map(mapRowToStorageThreadType);
1251
- return {
1252
- threads,
1253
- total,
1254
- page,
1255
- perPage: perPageForResponse,
1256
- hasMore: perPageInput === false ? false : offset + perPage < total
1257
- };
1258
- } catch (error$1) {
1259
- if (error$1 instanceof error.MastraError && error$1.category === error.ErrorCategory.USER) {
1260
- throw error$1;
1261
- }
1262
- const mastraError = new error.MastraError(
1263
- {
1264
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "FAILED"),
1265
- domain: error.ErrorDomain.STORAGE,
1266
- category: error.ErrorCategory.THIRD_PARTY,
1267
- text: `Error listing threads: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1268
- details: {
1269
- ...filter?.resourceId && { resourceId: filter.resourceId },
1270
- hasMetadataFilter: !!filter?.metadata
1271
- }
1272
- },
1273
- error$1
1274
- );
1275
- this.logger?.error(mastraError.toString());
1276
- this.logger?.trackException(mastraError);
1277
- return {
1278
- threads: [],
1279
- total: 0,
1280
- page,
1281
- perPage: perPageForResponse,
1282
- hasMore: false
1283
- };
1284
- }
1285
- }
1286
- async saveThread({ thread }) {
1287
- const fullTableName = this.#db.getTableName(storage.TABLE_THREADS);
1288
- const threadToSave = {
1289
- id: thread.id,
1290
- resourceId: thread.resourceId,
1291
- title: thread.title,
1292
- metadata: thread.metadata ? JSON.stringify(thread.metadata) : null,
1293
- createdAt: thread.createdAt.toISOString(),
1294
- updatedAt: thread.updatedAt.toISOString()
1295
- };
1296
- const processedRecord = await this.#db.processRecord(threadToSave);
1297
- const columns = Object.keys(processedRecord);
1298
- const values = Object.values(processedRecord);
1299
- const updateMap = {
1300
- resourceId: "excluded.resourceId",
1301
- title: "excluded.title",
1302
- metadata: "excluded.metadata",
1303
- createdAt: "excluded.createdAt",
1304
- updatedAt: "excluded.updatedAt"
1305
- };
1306
- const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], updateMap);
1307
- const { sql, params } = query.build();
1308
- try {
1309
- await this.#db.executeQuery({ sql, params });
1310
- return thread;
1311
- } catch (error$1) {
1312
- throw new error.MastraError(
1313
- {
1314
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "SAVE_THREAD", "FAILED"),
1315
- domain: error.ErrorDomain.STORAGE,
1316
- category: error.ErrorCategory.THIRD_PARTY,
1317
- text: `Failed to save thread to ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1318
- details: { threadId: thread.id }
1319
- },
1320
- error$1
1321
- );
1322
- }
1323
- }
1324
- async updateThread({
1325
- id,
1326
- title,
1327
- metadata
1328
- }) {
1329
- const thread = await this.getThreadById({ threadId: id });
1330
- try {
1331
- if (!thread) {
1332
- throw new Error(`Thread ${id} not found`);
1333
- }
1334
- const fullTableName = this.#db.getTableName(storage.TABLE_THREADS);
1335
- const mergedMetadata = {
1336
- ...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1337
- ...metadata
1338
- };
1339
- const updatedAt = /* @__PURE__ */ new Date();
1340
- const columns = ["title", "metadata", "updatedAt"];
1341
- const values = [title, JSON.stringify(mergedMetadata), updatedAt.toISOString()];
1342
- const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
1343
- const { sql, params } = query.build();
1344
- await this.#db.executeQuery({ sql, params });
1345
- return {
1346
- ...thread,
1347
- title,
1348
- metadata: {
1349
- ...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1350
- ...metadata
1351
- },
1352
- updatedAt
1353
- };
1354
- } catch (error$1) {
1355
- throw new error.MastraError(
1356
- {
1357
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "UPDATE_THREAD", "FAILED"),
1358
- domain: error.ErrorDomain.STORAGE,
1359
- category: error.ErrorCategory.THIRD_PARTY,
1360
- text: `Failed to update thread ${id}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1361
- details: { threadId: id }
1362
- },
1363
- error$1
1364
- );
1365
- }
1366
- }
1367
- async deleteThread({ threadId }) {
1368
- const fullTableName = this.#db.getTableName(storage.TABLE_THREADS);
1369
- try {
1370
- const deleteThreadQuery = createSqlBuilder().delete(fullTableName).where("id = ?", threadId);
1371
- const { sql: threadSql, params: threadParams } = deleteThreadQuery.build();
1372
- await this.#db.executeQuery({ sql: threadSql, params: threadParams });
1373
- const messagesTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1374
- const deleteMessagesQuery = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId);
1375
- const { sql: messagesSql, params: messagesParams } = deleteMessagesQuery.build();
1376
- await this.#db.executeQuery({ sql: messagesSql, params: messagesParams });
1377
- } catch (error$1) {
1378
- throw new error.MastraError(
1379
- {
1380
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "DELETE_THREAD", "FAILED"),
1381
- domain: error.ErrorDomain.STORAGE,
1382
- category: error.ErrorCategory.THIRD_PARTY,
1383
- text: `Failed to delete thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1384
- details: { threadId }
1385
- },
1386
- error$1
1387
- );
1388
- }
1389
- }
1390
- async saveMessages(args) {
1391
- const { messages } = args;
1392
- if (messages.length === 0) return { messages: [] };
1393
- try {
1394
- const now = /* @__PURE__ */ new Date();
1395
- const threadId = messages[0]?.threadId;
1396
- for (const [i, message] of messages.entries()) {
1397
- if (!message.id) throw new Error(`Message at index ${i} missing id`);
1398
- if (!message.threadId) {
1399
- throw new Error(`Message at index ${i} missing threadId`);
1400
- }
1401
- if (!message.content) {
1402
- throw new Error(`Message at index ${i} missing content`);
1403
- }
1404
- if (!message.role) {
1405
- throw new Error(`Message at index ${i} missing role`);
1406
- }
1407
- if (!message.resourceId) {
1408
- throw new Error(`Message at index ${i} missing resourceId`);
1409
- }
1410
- const thread = await this.getThreadById({ threadId: message.threadId });
1411
- if (!thread) {
1412
- throw new Error(`Thread ${message.threadId} not found`);
1413
- }
1414
- }
1415
- const messagesToInsert = messages.map((message) => {
1416
- const createdAt = message.createdAt ? new Date(message.createdAt) : now;
1417
- return {
1418
- id: message.id,
1419
- thread_id: message.threadId,
1420
- content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
1421
- createdAt: createdAt.toISOString(),
1422
- role: message.role,
1423
- type: message.type || "v2",
1424
- resourceId: message.resourceId
1425
- };
1426
- });
1427
- await Promise.all([
1428
- this.#db.batchUpsert({
1429
- tableName: storage.TABLE_MESSAGES,
1430
- records: messagesToInsert
1431
- }),
1432
- // Update thread's updatedAt timestamp
1433
- this.#db.executeQuery({
1434
- sql: `UPDATE ${this.#db.getTableName(storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
1435
- params: [now.toISOString(), threadId]
1436
- })
1437
- ]);
1438
- this.logger.debug(`Saved ${messages.length} messages`);
1439
- const list = new agent.MessageList().add(messages, "memory");
1440
- return { messages: list.get.all.db() };
1441
- } catch (error$1) {
1442
- throw new error.MastraError(
1443
- {
1444
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "SAVE_MESSAGES", "FAILED"),
1445
- domain: error.ErrorDomain.STORAGE,
1446
- category: error.ErrorCategory.THIRD_PARTY,
1447
- text: `Failed to save messages: ${error$1 instanceof Error ? error$1.message : String(error$1)}`
1448
- },
1449
- error$1
1450
- );
1451
- }
1452
- }
1453
- _sortMessages(messages, field, direction) {
1454
- return messages.sort((a, b) => {
1455
- const isDateField = field === "createdAt" || field === "updatedAt";
1456
- const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
1457
- const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
1458
- if (aValue === bValue) {
1459
- return a.id.localeCompare(b.id);
1460
- }
1461
- if (typeof aValue === "number" && typeof bValue === "number") {
1462
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
1463
- }
1464
- return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
1465
- });
1466
- }
1467
- async _getIncludedMessages(include) {
1468
- if (!include || include.length === 0) return null;
1469
- const tableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1470
- const targetIds = include.map((inc) => inc.id).filter(Boolean);
1471
- if (targetIds.length === 0) return null;
1472
- const idPlaceholders = targetIds.map(() => "?").join(", ");
1473
- const targetResult = await this.#db.executeQuery({
1474
- sql: `SELECT id, thread_id, createdAt FROM ${tableName} WHERE id IN (${idPlaceholders})`,
1475
- params: targetIds
1476
- });
1477
- if (!Array.isArray(targetResult) || targetResult.length === 0) return null;
1478
- const targetMap = new Map(
1479
- targetResult.map((r) => [r.id, { threadId: r.thread_id, createdAt: r.createdAt }])
1480
- );
1481
- const MAX_UNION_TERMS = 5;
1482
- const unionQueries = [];
1483
- const unionParams = [];
1484
- const allMessages = [];
1485
- const flushBatch = async () => {
1486
- if (unionQueries.length === 0) return;
1487
- const sql = unionQueries.length === 1 ? unionQueries[0] : `${unionQueries.join(" UNION ALL ")} ORDER BY createdAt ASC, id ASC`;
1488
- const result = await this.#db.executeQuery({ sql, params: unionParams });
1489
- if (Array.isArray(result)) {
1490
- allMessages.push(...result);
1491
- }
1492
- unionQueries.length = 0;
1493
- unionParams.length = 0;
1494
- };
1495
- for (const inc of include) {
1496
- const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1497
- const target = targetMap.get(id);
1498
- if (!target) continue;
1499
- const termsNeeded = withNextMessages > 0 ? 2 : 1;
1500
- if (unionQueries.length + termsNeeded > MAX_UNION_TERMS) {
1501
- await flushBatch();
1502
- }
1503
- unionQueries.push(`SELECT * FROM (
940
+ //#endregion
941
+ //#region src/storage/domains/memory/index.ts
942
+ function addSqliteMetadataFilter(conditions, params, metadataFilter) {
943
+ if (!metadataFilter) return;
944
+ for (const [key, value] of Object.entries(metadataFilter)) {
945
+ const path = `$.metadata.${key}`;
946
+ conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) IS NOT NULL ELSE 0 END`);
947
+ params.push(path);
948
+ addSqliteMetadataValuePredicate(conditions, params, path, value);
949
+ }
950
+ }
951
+ function addSqliteMetadataValuePredicate(conditions, params, path, value) {
952
+ if (value === null) {
953
+ conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = 'null' ELSE 0 END`);
954
+ params.push(path);
955
+ return;
956
+ }
957
+ if (typeof value === "string") {
958
+ conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = 'text' AND json_extract(content, ?) = ? ELSE 0 END`);
959
+ params.push(path, path, value);
960
+ return;
961
+ }
962
+ if (typeof value === "number") {
963
+ conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) IN ('integer', 'real') AND json_extract(content, ?) = ? ELSE 0 END`);
964
+ params.push(path, path, value);
965
+ return;
966
+ }
967
+ conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = ? AND json_extract(content, ?) = ? ELSE 0 END`);
968
+ params.push(path, value ? "true" : "false", path, value ? 1 : 0);
969
+ }
970
+ var MemoryStorageD1 = class extends _mastra_core_storage.MemoryStorage {
971
+ #db;
972
+ constructor(config) {
973
+ super();
974
+ this.#db = new D1DB(resolveD1Config(config));
975
+ }
976
+ async init() {
977
+ await this.#db.createTable({
978
+ tableName: _mastra_core_storage.TABLE_THREADS,
979
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_THREADS]
980
+ });
981
+ await this.#db.createTable({
982
+ tableName: _mastra_core_storage.TABLE_MESSAGES,
983
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_MESSAGES]
984
+ });
985
+ await this.#db.createTable({
986
+ tableName: _mastra_core_storage.TABLE_RESOURCES,
987
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_RESOURCES]
988
+ });
989
+ await this.#db.alterTable({
990
+ tableName: _mastra_core_storage.TABLE_MESSAGES,
991
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_MESSAGES],
992
+ ifNotExists: ["resourceId"]
993
+ });
994
+ }
995
+ async dangerouslyClearAll() {
996
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_MESSAGES });
997
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_THREADS });
998
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_RESOURCES });
999
+ }
1000
+ async getResourceById({ resourceId }) {
1001
+ const resource = await this.#db.load({
1002
+ tableName: _mastra_core_storage.TABLE_RESOURCES,
1003
+ keys: { id: resourceId }
1004
+ });
1005
+ if (!resource) return null;
1006
+ try {
1007
+ return {
1008
+ ...resource,
1009
+ createdAt: (0, _mastra_core_storage.ensureDate)(resource.createdAt),
1010
+ updatedAt: (0, _mastra_core_storage.ensureDate)(resource.updatedAt),
1011
+ metadata: typeof resource.metadata === "string" ? JSON.parse(resource.metadata || "{}") : resource.metadata
1012
+ };
1013
+ } catch (error) {
1014
+ const mastraError = new _mastra_core_error.MastraError({
1015
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_RESOURCE_BY_ID", "FAILED"),
1016
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1017
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1018
+ text: `Error processing resource ${resourceId}: ${error instanceof Error ? error.message : String(error)}`,
1019
+ details: { resourceId }
1020
+ }, error);
1021
+ this.logger?.error(mastraError.toString());
1022
+ this.logger?.trackException(mastraError);
1023
+ return null;
1024
+ }
1025
+ }
1026
+ async saveResource({ resource }) {
1027
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_RESOURCES);
1028
+ const resourceToSave = {
1029
+ id: resource.id,
1030
+ workingMemory: resource.workingMemory,
1031
+ metadata: resource.metadata ? JSON.stringify(resource.metadata) : null,
1032
+ createdAt: resource.createdAt,
1033
+ updatedAt: resource.updatedAt
1034
+ };
1035
+ const processedRecord = await this.#db.processRecord(resourceToSave);
1036
+ const columns = Object.keys(processedRecord);
1037
+ const values = Object.values(processedRecord);
1038
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], {
1039
+ workingMemory: "excluded.workingMemory",
1040
+ metadata: "excluded.metadata",
1041
+ createdAt: "excluded.createdAt",
1042
+ updatedAt: "excluded.updatedAt"
1043
+ }).build();
1044
+ try {
1045
+ await this.#db.executeQuery({
1046
+ sql,
1047
+ params
1048
+ });
1049
+ return resource;
1050
+ } catch (error) {
1051
+ throw new _mastra_core_error.MastraError({
1052
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_RESOURCE", "FAILED"),
1053
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1054
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1055
+ text: `Failed to save resource to ${fullTableName}: ${error instanceof Error ? error.message : String(error)}`,
1056
+ details: { resourceId: resource.id }
1057
+ }, error);
1058
+ }
1059
+ }
1060
+ async updateResource({ resourceId, workingMemory, metadata }) {
1061
+ const existingResource = await this.getResourceById({ resourceId });
1062
+ if (!existingResource) {
1063
+ const newResource = {
1064
+ id: resourceId,
1065
+ workingMemory,
1066
+ metadata: metadata || {},
1067
+ createdAt: /* @__PURE__ */ new Date(),
1068
+ updatedAt: /* @__PURE__ */ new Date()
1069
+ };
1070
+ return this.saveResource({ resource: newResource });
1071
+ }
1072
+ const updatedAt = /* @__PURE__ */ new Date();
1073
+ const updatedResource = {
1074
+ ...existingResource,
1075
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
1076
+ metadata: {
1077
+ ...existingResource.metadata,
1078
+ ...metadata
1079
+ },
1080
+ updatedAt
1081
+ };
1082
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_RESOURCES);
1083
+ const columns = [
1084
+ "workingMemory",
1085
+ "metadata",
1086
+ "updatedAt"
1087
+ ];
1088
+ const values = [
1089
+ updatedResource.workingMemory,
1090
+ JSON.stringify(updatedResource.metadata),
1091
+ updatedAt.toISOString()
1092
+ ];
1093
+ const { sql, params } = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", resourceId).build();
1094
+ try {
1095
+ await this.#db.executeQuery({
1096
+ sql,
1097
+ params
1098
+ });
1099
+ return updatedResource;
1100
+ } catch (error) {
1101
+ throw new _mastra_core_error.MastraError({
1102
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_RESOURCE", "FAILED"),
1103
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1104
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1105
+ text: `Failed to update resource ${resourceId}: ${error instanceof Error ? error.message : String(error)}`,
1106
+ details: { resourceId }
1107
+ }, error);
1108
+ }
1109
+ }
1110
+ async getThreadById({ threadId, resourceId }) {
1111
+ const thread = await this.#db.load({
1112
+ tableName: _mastra_core_storage.TABLE_THREADS,
1113
+ keys: { id: threadId }
1114
+ });
1115
+ if (!thread || resourceId !== void 0 && thread.resourceId !== resourceId) return null;
1116
+ try {
1117
+ return {
1118
+ ...thread,
1119
+ createdAt: (0, _mastra_core_storage.ensureDate)(thread.createdAt),
1120
+ updatedAt: (0, _mastra_core_storage.ensureDate)(thread.updatedAt),
1121
+ metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
1122
+ };
1123
+ } catch (error) {
1124
+ const mastraError = new _mastra_core_error.MastraError({
1125
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_THREAD_BY_ID", "FAILED"),
1126
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1127
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1128
+ text: `Error processing thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,
1129
+ details: { threadId }
1130
+ }, error);
1131
+ this.logger?.error(mastraError.toString());
1132
+ this.logger?.trackException(mastraError);
1133
+ return null;
1134
+ }
1135
+ }
1136
+ async listThreads(args) {
1137
+ const { page = 0, perPage: perPageInput, orderBy, filter } = args;
1138
+ try {
1139
+ this.validatePaginationInput(page, perPageInput ?? 100);
1140
+ } catch (error) {
1141
+ throw new _mastra_core_error.MastraError({
1142
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_PAGE"),
1143
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1144
+ category: _mastra_core_error.ErrorCategory.USER,
1145
+ details: {
1146
+ page,
1147
+ ...perPageInput !== void 0 && { perPage: perPageInput }
1148
+ }
1149
+ }, error instanceof Error ? error : /* @__PURE__ */ new Error("Invalid pagination parameters"));
1150
+ }
1151
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
1152
+ try {
1153
+ this.validateMetadataKeys(filter?.metadata);
1154
+ } catch (error) {
1155
+ throw new _mastra_core_error.MastraError({
1156
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_KEY"),
1157
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1158
+ category: _mastra_core_error.ErrorCategory.USER,
1159
+ details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
1160
+ }, error instanceof Error ? error : /* @__PURE__ */ new Error("Invalid metadata key"));
1161
+ }
1162
+ const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
1163
+ const { field, direction } = this.parseOrderBy(orderBy);
1164
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1165
+ const mapRowToStorageThreadType = (row) => ({
1166
+ ...row,
1167
+ createdAt: (0, _mastra_core_storage.ensureDate)(row.createdAt),
1168
+ updatedAt: (0, _mastra_core_storage.ensureDate)(row.updatedAt),
1169
+ metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
1170
+ });
1171
+ try {
1172
+ let countQuery = createSqlBuilder().count().from(fullTableName);
1173
+ let selectQuery = createSqlBuilder().select("*").from(fullTableName);
1174
+ if (filter?.resourceId) {
1175
+ countQuery = countQuery.whereAnd("resourceId = ?", filter.resourceId);
1176
+ selectQuery = selectQuery.whereAnd("resourceId = ?", filter.resourceId);
1177
+ }
1178
+ if (filter?.metadata && Object.keys(filter.metadata).length > 0) for (const [key, value] of Object.entries(filter.metadata)) {
1179
+ if (value !== null && typeof value === "object") throw new _mastra_core_error.MastraError({
1180
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_VALUE"),
1181
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1182
+ category: _mastra_core_error.ErrorCategory.USER,
1183
+ text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${Array.isArray(value) ? "array" : "object"}`,
1184
+ details: {
1185
+ key,
1186
+ valueType: Array.isArray(value) ? "array" : "object"
1187
+ }
1188
+ }, /* @__PURE__ */ new Error("Invalid metadata filter value type"));
1189
+ if (value === null) {
1190
+ const condition = `json_extract(metadata, '$.${key}') IS NULL`;
1191
+ countQuery = countQuery.whereAnd(condition);
1192
+ selectQuery = selectQuery.whereAnd(condition);
1193
+ } else {
1194
+ const condition = `json_extract(metadata, '$.${key}') = ?`;
1195
+ const filterValue = value;
1196
+ countQuery = countQuery.whereAnd(condition, filterValue);
1197
+ selectQuery = selectQuery.whereAnd(condition, filterValue);
1198
+ }
1199
+ }
1200
+ const countResult = await this.#db.executeQuery(countQuery.build());
1201
+ const total = Number(countResult?.[0]?.count ?? 0);
1202
+ if (total === 0) return {
1203
+ threads: [],
1204
+ total: 0,
1205
+ page,
1206
+ perPage: perPageForResponse,
1207
+ hasMore: false
1208
+ };
1209
+ const limitValue = perPageInput === false ? total : perPage;
1210
+ selectQuery = selectQuery.orderBy(field, direction).limit(limitValue).offset(offset);
1211
+ return {
1212
+ threads: (await this.#db.executeQuery(selectQuery.build())).map(mapRowToStorageThreadType),
1213
+ total,
1214
+ page,
1215
+ perPage: perPageForResponse,
1216
+ hasMore: perPageInput === false ? false : offset + perPage < total
1217
+ };
1218
+ } catch (error) {
1219
+ if (error instanceof _mastra_core_error.MastraError && error.category === _mastra_core_error.ErrorCategory.USER) throw error;
1220
+ const mastraError = new _mastra_core_error.MastraError({
1221
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "FAILED"),
1222
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1223
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1224
+ text: `Error listing threads: ${error instanceof Error ? error.message : String(error)}`,
1225
+ details: {
1226
+ ...filter?.resourceId && { resourceId: filter.resourceId },
1227
+ hasMetadataFilter: !!filter?.metadata
1228
+ }
1229
+ }, error);
1230
+ this.logger?.error(mastraError.toString());
1231
+ this.logger?.trackException(mastraError);
1232
+ return {
1233
+ threads: [],
1234
+ total: 0,
1235
+ page,
1236
+ perPage: perPageForResponse,
1237
+ hasMore: false
1238
+ };
1239
+ }
1240
+ }
1241
+ async saveThread({ thread }) {
1242
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1243
+ const threadToSave = {
1244
+ id: thread.id,
1245
+ resourceId: thread.resourceId,
1246
+ title: thread.title,
1247
+ metadata: thread.metadata ? JSON.stringify(thread.metadata) : null,
1248
+ createdAt: thread.createdAt.toISOString(),
1249
+ updatedAt: thread.updatedAt.toISOString()
1250
+ };
1251
+ const processedRecord = await this.#db.processRecord(threadToSave);
1252
+ const columns = Object.keys(processedRecord);
1253
+ const values = Object.values(processedRecord);
1254
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], {
1255
+ resourceId: "excluded.resourceId",
1256
+ title: "excluded.title",
1257
+ metadata: "excluded.metadata",
1258
+ createdAt: "excluded.createdAt",
1259
+ updatedAt: "excluded.updatedAt"
1260
+ }).build();
1261
+ try {
1262
+ await this.#db.executeQuery({
1263
+ sql,
1264
+ params
1265
+ });
1266
+ return thread;
1267
+ } catch (error) {
1268
+ throw new _mastra_core_error.MastraError({
1269
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_THREAD", "FAILED"),
1270
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1271
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1272
+ text: `Failed to save thread to ${fullTableName}: ${error instanceof Error ? error.message : String(error)}`,
1273
+ details: { threadId: thread.id }
1274
+ }, error);
1275
+ }
1276
+ }
1277
+ async updateThread({ id, title, metadata }) {
1278
+ const thread = await this.getThreadById({ threadId: id });
1279
+ try {
1280
+ if (!thread) throw new Error(`Thread ${id} not found`);
1281
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1282
+ const mergedMetadata = {
1283
+ ...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1284
+ ...metadata
1285
+ };
1286
+ const updatedAt = /* @__PURE__ */ new Date();
1287
+ const columns = [
1288
+ "title",
1289
+ "metadata",
1290
+ "updatedAt"
1291
+ ];
1292
+ const values = [
1293
+ title,
1294
+ JSON.stringify(mergedMetadata),
1295
+ updatedAt.toISOString()
1296
+ ];
1297
+ const { sql, params } = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id).build();
1298
+ await this.#db.executeQuery({
1299
+ sql,
1300
+ params
1301
+ });
1302
+ return {
1303
+ ...thread,
1304
+ title,
1305
+ metadata: {
1306
+ ...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1307
+ ...metadata
1308
+ },
1309
+ updatedAt
1310
+ };
1311
+ } catch (error) {
1312
+ throw new _mastra_core_error.MastraError({
1313
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_THREAD", "FAILED"),
1314
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1315
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1316
+ text: `Failed to update thread ${id}: ${error instanceof Error ? error.message : String(error)}`,
1317
+ details: { threadId: id }
1318
+ }, error);
1319
+ }
1320
+ }
1321
+ async deleteThread({ threadId }) {
1322
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1323
+ try {
1324
+ const { sql: threadSql, params: threadParams } = createSqlBuilder().delete(fullTableName).where("id = ?", threadId).build();
1325
+ await this.#db.executeQuery({
1326
+ sql: threadSql,
1327
+ params: threadParams
1328
+ });
1329
+ const messagesTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1330
+ const { sql: messagesSql, params: messagesParams } = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId).build();
1331
+ await this.#db.executeQuery({
1332
+ sql: messagesSql,
1333
+ params: messagesParams
1334
+ });
1335
+ } catch (error) {
1336
+ throw new _mastra_core_error.MastraError({
1337
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_THREAD", "FAILED"),
1338
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1339
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1340
+ text: `Failed to delete thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,
1341
+ details: { threadId }
1342
+ }, error);
1343
+ }
1344
+ }
1345
+ async saveMessages(args) {
1346
+ const { messages } = args;
1347
+ if (messages.length === 0) return { messages: [] };
1348
+ try {
1349
+ const now = /* @__PURE__ */ new Date();
1350
+ const threadId = messages[0]?.threadId;
1351
+ for (const [i, message] of messages.entries()) {
1352
+ if (!message.id) throw new Error(`Message at index ${i} missing id`);
1353
+ if (!message.threadId) throw new Error(`Message at index ${i} missing threadId`);
1354
+ if (!message.content) throw new Error(`Message at index ${i} missing content`);
1355
+ if (!message.role) throw new Error(`Message at index ${i} missing role`);
1356
+ if (!message.resourceId) throw new Error(`Message at index ${i} missing resourceId`);
1357
+ if (!await this.getThreadById({ threadId: message.threadId })) throw new Error(`Thread ${message.threadId} not found`);
1358
+ }
1359
+ const messagesToInsert = messages.map((message) => {
1360
+ const createdAt = message.createdAt ? new Date(message.createdAt) : now;
1361
+ return {
1362
+ id: message.id,
1363
+ thread_id: message.threadId,
1364
+ content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
1365
+ createdAt: createdAt.toISOString(),
1366
+ role: message.role,
1367
+ type: message.type || "v2",
1368
+ resourceId: message.resourceId
1369
+ };
1370
+ });
1371
+ await Promise.all([this.#db.batchUpsert({
1372
+ tableName: _mastra_core_storage.TABLE_MESSAGES,
1373
+ records: messagesToInsert
1374
+ }), this.#db.executeQuery({
1375
+ sql: `UPDATE ${this.#db.getTableName(_mastra_core_storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
1376
+ params: [now.toISOString(), threadId]
1377
+ })]);
1378
+ this.logger.debug(`Saved ${messages.length} messages`);
1379
+ return { messages: new _mastra_core_agent.MessageList().add(messages, "memory").get.all.db() };
1380
+ } catch (error) {
1381
+ throw new _mastra_core_error.MastraError({
1382
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_MESSAGES", "FAILED"),
1383
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1384
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1385
+ text: `Failed to save messages: ${error instanceof Error ? error.message : String(error)}`
1386
+ }, error);
1387
+ }
1388
+ }
1389
+ _sortMessages(messages, field, direction) {
1390
+ return messages.sort((a, b) => {
1391
+ const isDateField = field === "createdAt" || field === "updatedAt";
1392
+ const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
1393
+ const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
1394
+ if (aValue === bValue) return a.id.localeCompare(b.id);
1395
+ if (typeof aValue === "number" && typeof bValue === "number") return direction === "ASC" ? aValue - bValue : bValue - aValue;
1396
+ return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
1397
+ });
1398
+ }
1399
+ async _getIncludedMessages(include) {
1400
+ if (!include || include.length === 0) return null;
1401
+ const tableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1402
+ const targetIds = include.map((inc) => inc.id).filter(Boolean);
1403
+ if (targetIds.length === 0) return null;
1404
+ const idPlaceholders = targetIds.map(() => "?").join(", ");
1405
+ const targetResult = await this.#db.executeQuery({
1406
+ sql: `SELECT id, thread_id, createdAt FROM ${tableName} WHERE id IN (${idPlaceholders})`,
1407
+ params: targetIds
1408
+ });
1409
+ if (!Array.isArray(targetResult) || targetResult.length === 0) return null;
1410
+ const targetMap = new Map(targetResult.map((r) => [r.id, {
1411
+ threadId: r.thread_id,
1412
+ createdAt: r.createdAt
1413
+ }]));
1414
+ const MAX_UNION_TERMS = 5;
1415
+ const unionQueries = [];
1416
+ const unionParams = [];
1417
+ const allMessages = [];
1418
+ const flushBatch = async () => {
1419
+ if (unionQueries.length === 0) return;
1420
+ const sql = unionQueries.length === 1 ? unionQueries[0] : `${unionQueries.join(" UNION ALL ")} ORDER BY createdAt ASC, id ASC`;
1421
+ const result = await this.#db.executeQuery({
1422
+ sql,
1423
+ params: unionParams
1424
+ });
1425
+ if (Array.isArray(result)) allMessages.push(...result);
1426
+ unionQueries.length = 0;
1427
+ unionParams.length = 0;
1428
+ };
1429
+ for (const inc of include) {
1430
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1431
+ const target = targetMap.get(id);
1432
+ if (!target) continue;
1433
+ const termsNeeded = withNextMessages > 0 ? 2 : 1;
1434
+ if (unionQueries.length + termsNeeded > MAX_UNION_TERMS) await flushBatch();
1435
+ unionQueries.push(`SELECT * FROM (
1504
1436
  SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
1505
1437
  FROM ${tableName}
1506
1438
  WHERE thread_id = ?
@@ -1508,9 +1440,9 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
1508
1440
  ORDER BY createdAt DESC, id DESC
1509
1441
  LIMIT ?
1510
1442
  )`);
1511
- unionParams.push(target.threadId, target.createdAt, withPreviousMessages + 1);
1512
- if (withNextMessages > 0) {
1513
- unionQueries.push(`SELECT * FROM (
1443
+ unionParams.push(target.threadId, target.createdAt, withPreviousMessages + 1);
1444
+ if (withNextMessages > 0) {
1445
+ unionQueries.push(`SELECT * FROM (
1514
1446
  SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
1515
1447
  FROM ${tableName}
1516
1448
  WHERE thread_id = ?
@@ -1518,1048 +1450,1017 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
1518
1450
  ORDER BY createdAt ASC, id ASC
1519
1451
  LIMIT ?
1520
1452
  )`);
1521
- unionParams.push(target.threadId, target.createdAt, withNextMessages);
1522
- }
1523
- }
1524
- await flushBatch();
1525
- const seen = /* @__PURE__ */ new Set();
1526
- const processedMessages = allMessages.filter((message) => {
1527
- const id = message.id;
1528
- if (seen.has(id)) return false;
1529
- seen.add(id);
1530
- return true;
1531
- }).map((message) => {
1532
- const processedMsg = {};
1533
- for (const [key, value] of Object.entries(message)) {
1534
- if (key === `type` && value === `v2`) continue;
1535
- processedMsg[key] = deserializeValue(value);
1536
- }
1537
- return processedMsg;
1538
- });
1539
- return processedMessages;
1540
- }
1541
- async listMessagesById({ messageIds }) {
1542
- if (messageIds.length === 0) return { messages: [] };
1543
- const fullTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1544
- const messages = [];
1545
- try {
1546
- const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId", "resourceId"]).from(fullTableName).where(`id in (${messageIds.map(() => "?").join(",")})`, ...messageIds);
1547
- query.orderBy("createdAt", "DESC");
1548
- const { sql, params } = query.build();
1549
- const result = await this.#db.executeQuery({ sql, params });
1550
- if (Array.isArray(result)) messages.push(...result);
1551
- const processedMessages = messages.map((message) => {
1552
- const processedMsg = {};
1553
- for (const [key, value] of Object.entries(message)) {
1554
- if (key === `type` && value === `v2`) continue;
1555
- processedMsg[key] = deserializeValue(value);
1556
- }
1557
- return processedMsg;
1558
- });
1559
- this.logger.debug(`Retrieved ${messages.length} messages`);
1560
- const list = new agent.MessageList().add(processedMessages, "memory");
1561
- return { messages: list.get.all.db() };
1562
- } catch (error$1) {
1563
- const mastraError = new error.MastraError(
1564
- {
1565
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_MESSAGES_BY_ID", "FAILED"),
1566
- domain: error.ErrorDomain.STORAGE,
1567
- category: error.ErrorCategory.THIRD_PARTY,
1568
- text: `Failed to retrieve messages by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1569
- details: { messageIds: JSON.stringify(messageIds) }
1570
- },
1571
- error$1
1572
- );
1573
- this.logger?.error(mastraError.toString());
1574
- this.logger?.trackException(mastraError);
1575
- throw mastraError;
1576
- }
1577
- }
1578
- async listMessages(args) {
1579
- const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1580
- const threadIds = Array.isArray(threadId) ? threadId : [threadId];
1581
- if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
1582
- throw new error.MastraError(
1583
- {
1584
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_THREAD_ID"),
1585
- domain: error.ErrorDomain.STORAGE,
1586
- category: error.ErrorCategory.THIRD_PARTY,
1587
- details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
1588
- },
1589
- new Error("threadId must be a non-empty string or array of non-empty strings")
1590
- );
1591
- }
1592
- if (page < 0) {
1593
- throw new error.MastraError(
1594
- {
1595
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_PAGE"),
1596
- domain: error.ErrorDomain.STORAGE,
1597
- category: error.ErrorCategory.USER,
1598
- details: { page }
1599
- },
1600
- new Error("page must be >= 0")
1601
- );
1602
- }
1603
- const perPage = storage.normalizePerPage(perPageInput, 40);
1604
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1605
- try {
1606
- const fullTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1607
- let query = `
1453
+ unionParams.push(target.threadId, target.createdAt, withNextMessages);
1454
+ }
1455
+ }
1456
+ await flushBatch();
1457
+ const seen = /* @__PURE__ */ new Set();
1458
+ return allMessages.filter((message) => {
1459
+ const id = message.id;
1460
+ if (seen.has(id)) return false;
1461
+ seen.add(id);
1462
+ return true;
1463
+ }).map((message) => {
1464
+ const processedMsg = {};
1465
+ for (const [key, value] of Object.entries(message)) {
1466
+ if (key === `type` && value === `v2`) continue;
1467
+ processedMsg[key] = deserializeValue(value);
1468
+ }
1469
+ return processedMsg;
1470
+ });
1471
+ }
1472
+ async listMessagesById({ messageIds }) {
1473
+ if (messageIds.length === 0) return { messages: [] };
1474
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1475
+ const messages = [];
1476
+ try {
1477
+ const query = createSqlBuilder().select([
1478
+ "id",
1479
+ "content",
1480
+ "role",
1481
+ "type",
1482
+ "createdAt",
1483
+ "thread_id AS threadId",
1484
+ "resourceId"
1485
+ ]).from(fullTableName).where(`id in (${messageIds.map(() => "?").join(",")})`, ...messageIds);
1486
+ query.orderBy("createdAt", "DESC");
1487
+ const { sql, params } = query.build();
1488
+ const result = await this.#db.executeQuery({
1489
+ sql,
1490
+ params
1491
+ });
1492
+ if (Array.isArray(result)) messages.push(...result);
1493
+ const processedMessages = messages.map((message) => {
1494
+ const processedMsg = {};
1495
+ for (const [key, value] of Object.entries(message)) {
1496
+ if (key === `type` && value === `v2`) continue;
1497
+ processedMsg[key] = deserializeValue(value);
1498
+ }
1499
+ return processedMsg;
1500
+ });
1501
+ this.logger.debug(`Retrieved ${messages.length} messages`);
1502
+ return { messages: new _mastra_core_agent.MessageList().add(processedMessages, "memory").get.all.db() };
1503
+ } catch (error) {
1504
+ const mastraError = new _mastra_core_error.MastraError({
1505
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES_BY_ID", "FAILED"),
1506
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1507
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1508
+ text: `Failed to retrieve messages by ID: ${error instanceof Error ? error.message : String(error)}`,
1509
+ details: { messageIds: JSON.stringify(messageIds) }
1510
+ }, error);
1511
+ this.logger?.error(mastraError.toString());
1512
+ this.logger?.trackException(mastraError);
1513
+ throw mastraError;
1514
+ }
1515
+ }
1516
+ async listMessages(args) {
1517
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1518
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
1519
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) throw new _mastra_core_error.MastraError({
1520
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_THREAD_ID"),
1521
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1522
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1523
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
1524
+ }, /* @__PURE__ */ new Error("threadId must be a non-empty string or array of non-empty strings"));
1525
+ if (page < 0) throw new _mastra_core_error.MastraError({
1526
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_PAGE"),
1527
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1528
+ category: _mastra_core_error.ErrorCategory.USER,
1529
+ details: { page }
1530
+ }, /* @__PURE__ */ new Error("page must be >= 0"));
1531
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 40);
1532
+ const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
1533
+ const metadataFilter = (0, _mastra_core_storage.validateStorageMetadataFilter)(filter?.metadata);
1534
+ try {
1535
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1536
+ const threadPlaceholders = threadIds.map(() => "?").join(", ");
1537
+ let query = `
1608
1538
  SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
1609
1539
  FROM ${fullTableName}
1610
- WHERE thread_id = ?
1540
+ WHERE thread_id IN (${threadPlaceholders})
1611
1541
  `;
1612
- const queryParams = [threadId];
1613
- if (resourceId) {
1614
- query += ` AND resourceId = ?`;
1615
- queryParams.push(resourceId);
1616
- }
1617
- const dateRange = filter?.dateRange;
1618
- if (dateRange?.start) {
1619
- const startDate = dateRange.start instanceof Date ? storage.serializeDate(dateRange.start) : storage.serializeDate(new Date(dateRange.start));
1620
- const startOp = dateRange.startExclusive ? ">" : ">=";
1621
- query += ` AND createdAt ${startOp} ?`;
1622
- queryParams.push(startDate);
1623
- }
1624
- if (dateRange?.end) {
1625
- const endDate = dateRange.end instanceof Date ? storage.serializeDate(dateRange.end) : storage.serializeDate(new Date(dateRange.end));
1626
- const endOp = dateRange.endExclusive ? "<" : "<=";
1627
- query += ` AND createdAt ${endOp} ?`;
1628
- queryParams.push(endDate);
1629
- }
1630
- const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1631
- if (perPage === 0 && (!include || include.length === 0)) {
1632
- return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
1633
- }
1634
- if (perPage === 0 && include && include.length > 0) {
1635
- const includeResult = await this._getIncludedMessages(include);
1636
- if (!Array.isArray(includeResult) || includeResult.length === 0) {
1637
- return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
1638
- }
1639
- const list2 = new agent.MessageList().add(includeResult, "memory");
1640
- return {
1641
- messages: this._sortMessages(list2.get.all.db(), field, direction),
1642
- total: 0,
1643
- page,
1644
- perPage: perPageForResponse,
1645
- hasMore: false
1646
- };
1647
- }
1648
- query += ` ORDER BY "${field}" ${direction}`;
1649
- if (perPage !== Number.MAX_SAFE_INTEGER) {
1650
- query += ` LIMIT ? OFFSET ?`;
1651
- queryParams.push(perPage, offset);
1652
- }
1653
- const results = await this.#db.executeQuery({ sql: query, params: queryParams });
1654
- const paginatedMessages = (isArrayOfRecords(results) ? results : []).map((message) => {
1655
- const processedMsg = {};
1656
- for (const [key, value] of Object.entries(message)) {
1657
- if (key === `type` && value === `v2`) continue;
1658
- processedMsg[key] = deserializeValue(value);
1659
- }
1660
- return processedMsg;
1661
- });
1662
- const paginatedCount = paginatedMessages.length;
1663
- let countQuery = `SELECT count() as count FROM ${fullTableName} WHERE thread_id = ?`;
1664
- const countParams = [threadId];
1665
- if (resourceId) {
1666
- countQuery += ` AND resourceId = ?`;
1667
- countParams.push(resourceId);
1668
- }
1669
- if (dateRange?.start) {
1670
- const startDate = dateRange.start instanceof Date ? storage.serializeDate(dateRange.start) : storage.serializeDate(new Date(dateRange.start));
1671
- const startOp = dateRange.startExclusive ? ">" : ">=";
1672
- countQuery += ` AND createdAt ${startOp} ?`;
1673
- countParams.push(startDate);
1674
- }
1675
- if (dateRange?.end) {
1676
- const endDate = dateRange.end instanceof Date ? storage.serializeDate(dateRange.end) : storage.serializeDate(new Date(dateRange.end));
1677
- const endOp = dateRange.endExclusive ? "<" : "<=";
1678
- countQuery += ` AND createdAt ${endOp} ?`;
1679
- countParams.push(endDate);
1680
- }
1681
- const countResult = await this.#db.executeQuery({ sql: countQuery, params: countParams });
1682
- const total = Number(countResult[0]?.count ?? 0);
1683
- if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
1684
- return {
1685
- messages: [],
1686
- total: 0,
1687
- page,
1688
- perPage: perPageForResponse,
1689
- hasMore: false
1690
- };
1691
- }
1692
- const messageIds = new Set(paginatedMessages.map((m) => m.id));
1693
- let includeMessages = [];
1694
- if (include && include.length > 0) {
1695
- const includeResult = await this._getIncludedMessages(include);
1696
- if (Array.isArray(includeResult)) {
1697
- includeMessages = includeResult;
1698
- for (const includeMsg of includeMessages) {
1699
- if (!messageIds.has(includeMsg.id)) {
1700
- paginatedMessages.push(includeMsg);
1701
- messageIds.add(includeMsg.id);
1702
- }
1703
- }
1704
- }
1705
- }
1706
- const list = new agent.MessageList().add(paginatedMessages, "memory");
1707
- const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
1708
- const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1709
- const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1710
- const hasMore = perPageInput === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
1711
- return {
1712
- messages: finalMessages,
1713
- total,
1714
- page,
1715
- perPage: perPageForResponse,
1716
- hasMore
1717
- };
1718
- } catch (error$1) {
1719
- const mastraError = new error.MastraError(
1720
- {
1721
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_MESSAGES", "FAILED"),
1722
- domain: error.ErrorDomain.STORAGE,
1723
- category: error.ErrorCategory.THIRD_PARTY,
1724
- text: `Failed to list messages for thread ${Array.isArray(threadId) ? threadId.join(",") : threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1725
- details: {
1726
- threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1727
- resourceId: resourceId ?? ""
1728
- }
1729
- },
1730
- error$1
1731
- );
1732
- this.logger?.error?.(mastraError.toString());
1733
- this.logger?.trackException?.(mastraError);
1734
- return {
1735
- messages: [],
1736
- total: 0,
1737
- page,
1738
- perPage: perPageForResponse,
1739
- hasMore: false
1740
- };
1741
- }
1742
- }
1743
- async updateMessages(args) {
1744
- const { messages } = args;
1745
- this.logger.debug("Updating messages", { count: messages.length });
1746
- if (!messages.length) {
1747
- return [];
1748
- }
1749
- const messageIds = messages.map((m) => m.id);
1750
- const fullTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1751
- const threadsTableName = this.#db.getTableName(storage.TABLE_THREADS);
1752
- try {
1753
- const placeholders = messageIds.map(() => "?").join(",");
1754
- const selectQuery = `SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId FROM ${fullTableName} WHERE id IN (${placeholders})`;
1755
- const existingMessages = await this.#db.executeQuery({ sql: selectQuery, params: messageIds });
1756
- if (existingMessages.length === 0) {
1757
- return [];
1758
- }
1759
- const parsedExistingMessages = existingMessages.map((msg) => {
1760
- if (typeof msg.content === "string") {
1761
- try {
1762
- msg.content = JSON.parse(msg.content);
1763
- } catch {
1764
- }
1765
- }
1766
- return msg;
1767
- });
1768
- const threadIdsToUpdate = /* @__PURE__ */ new Set();
1769
- const updateQueries = [];
1770
- for (const existingMessage of parsedExistingMessages) {
1771
- const updatePayload = messages.find((m) => m.id === existingMessage.id);
1772
- if (!updatePayload) continue;
1773
- const { id, ...fieldsToUpdate } = updatePayload;
1774
- if (Object.keys(fieldsToUpdate).length === 0) continue;
1775
- threadIdsToUpdate.add(existingMessage.threadId);
1776
- if ("threadId" in updatePayload && updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
1777
- threadIdsToUpdate.add(updatePayload.threadId);
1778
- }
1779
- const setClauses = [];
1780
- const values = [];
1781
- const updatableFields = { ...fieldsToUpdate };
1782
- if (updatableFields.content) {
1783
- const existingContent = existingMessage.content || {};
1784
- const newContent = {
1785
- ...existingContent,
1786
- ...updatableFields.content,
1787
- // Deep merge metadata if it exists on both
1788
- ...existingContent?.metadata && updatableFields.content.metadata ? {
1789
- metadata: {
1790
- ...existingContent.metadata,
1791
- ...updatableFields.content.metadata
1792
- }
1793
- } : {}
1794
- };
1795
- setClauses.push(`content = ?`);
1796
- values.push(JSON.stringify(newContent));
1797
- delete updatableFields.content;
1798
- }
1799
- for (const key in updatableFields) {
1800
- if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
1801
- const dbColumn = key === "threadId" ? "thread_id" : key;
1802
- setClauses.push(`${dbColumn} = ?`);
1803
- values.push(updatableFields[key]);
1804
- }
1805
- }
1806
- if (setClauses.length > 0) {
1807
- values.push(id);
1808
- const updateQuery = `UPDATE ${fullTableName} SET ${setClauses.join(", ")} WHERE id = ?`;
1809
- updateQueries.push({ sql: updateQuery, params: values });
1810
- }
1811
- }
1812
- for (const query of updateQueries) {
1813
- await this.#db.executeQuery(query);
1814
- }
1815
- if (threadIdsToUpdate.size > 0) {
1816
- const threadPlaceholders = Array.from(threadIdsToUpdate).map(() => "?").join(",");
1817
- const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${threadPlaceholders})`;
1818
- const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...Array.from(threadIdsToUpdate)];
1819
- await this.#db.executeQuery({ sql: threadUpdateQuery, params: threadUpdateParams });
1820
- }
1821
- const updatedMessages = await this.#db.executeQuery({ sql: selectQuery, params: messageIds });
1822
- return updatedMessages.map((message) => {
1823
- if (typeof message.content === "string") {
1824
- try {
1825
- message.content = JSON.parse(message.content);
1826
- } catch {
1827
- }
1828
- }
1829
- return message;
1830
- });
1831
- } catch (error$1) {
1832
- throw new error.MastraError(
1833
- {
1834
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "UPDATE_MESSAGES", "FAILED"),
1835
- domain: error.ErrorDomain.STORAGE,
1836
- category: error.ErrorCategory.THIRD_PARTY,
1837
- details: { count: messages.length }
1838
- },
1839
- error$1
1840
- );
1841
- }
1842
- }
1843
- async deleteMessages(messageIds) {
1844
- if (messageIds.length === 0) return;
1845
- const fullTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
1846
- const threadsTableName = this.#db.getTableName(storage.TABLE_THREADS);
1847
- try {
1848
- const placeholders = messageIds.map(() => "?").join(",");
1849
- const selectQuery = `SELECT DISTINCT thread_id FROM ${fullTableName} WHERE id IN (${placeholders})`;
1850
- const threadResults = await this.#db.executeQuery({ sql: selectQuery, params: messageIds });
1851
- const threadIds = threadResults.map((r) => r.thread_id).filter(Boolean);
1852
- const deleteQuery = createSqlBuilder().delete(fullTableName).where(`id IN (${placeholders})`, ...messageIds);
1853
- const { sql, params } = deleteQuery.build();
1854
- await this.#db.executeQuery({ sql, params });
1855
- if (threadIds.length > 0) {
1856
- const threadPlaceholders = threadIds.map(() => "?").join(",");
1857
- const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${threadPlaceholders})`;
1858
- const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...threadIds];
1859
- await this.#db.executeQuery({ sql: threadUpdateQuery, params: threadUpdateParams });
1860
- }
1861
- } catch (error$1) {
1862
- throw new error.MastraError(
1863
- {
1864
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "DELETE_MESSAGES", "FAILED"),
1865
- domain: error.ErrorDomain.STORAGE,
1866
- category: error.ErrorCategory.THIRD_PARTY,
1867
- details: { messageIds: JSON.stringify(messageIds) }
1868
- },
1869
- error$1
1870
- );
1871
- }
1872
- }
1542
+ const queryParams = [...threadIds];
1543
+ if (resourceId) {
1544
+ query += ` AND resourceId = ?`;
1545
+ queryParams.push(resourceId);
1546
+ }
1547
+ const dateRange = filter?.dateRange;
1548
+ if (dateRange?.start) {
1549
+ const startDate = dateRange.start instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.start) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.start));
1550
+ const startOp = dateRange.startExclusive ? ">" : ">=";
1551
+ query += ` AND createdAt ${startOp} ?`;
1552
+ queryParams.push(startDate);
1553
+ }
1554
+ if (dateRange?.end) {
1555
+ const endDate = dateRange.end instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.end) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.end));
1556
+ const endOp = dateRange.endExclusive ? "<" : "<=";
1557
+ query += ` AND createdAt ${endOp} ?`;
1558
+ queryParams.push(endDate);
1559
+ }
1560
+ const metadataConditions = [];
1561
+ addSqliteMetadataFilter(metadataConditions, queryParams, metadataFilter);
1562
+ if (metadataConditions.length > 0) query += ` AND ${metadataConditions.join(" AND ")}`;
1563
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1564
+ if (perPage === 0 && (!include || include.length === 0)) return {
1565
+ messages: [],
1566
+ total: 0,
1567
+ page,
1568
+ perPage: perPageForResponse,
1569
+ hasMore: false
1570
+ };
1571
+ if (perPage === 0 && include && include.length > 0) {
1572
+ const includeResult = await this._getIncludedMessages(include);
1573
+ if (!Array.isArray(includeResult) || includeResult.length === 0) return {
1574
+ messages: [],
1575
+ total: 0,
1576
+ page,
1577
+ perPage: perPageForResponse,
1578
+ hasMore: false
1579
+ };
1580
+ const list = new _mastra_core_agent.MessageList().add(includeResult, "memory");
1581
+ return {
1582
+ messages: this._sortMessages(list.get.all.db(), field, direction),
1583
+ total: 0,
1584
+ page,
1585
+ perPage: perPageForResponse,
1586
+ hasMore: false
1587
+ };
1588
+ }
1589
+ query += ` ORDER BY "${field}" ${direction}`;
1590
+ if (perPage !== Number.MAX_SAFE_INTEGER) {
1591
+ query += ` LIMIT ? OFFSET ?`;
1592
+ queryParams.push(perPage, offset);
1593
+ }
1594
+ const results = await this.#db.executeQuery({
1595
+ sql: query,
1596
+ params: queryParams
1597
+ });
1598
+ const paginatedMessages = (isArrayOfRecords(results) ? results : []).map((message) => {
1599
+ const processedMsg = {};
1600
+ for (const [key, value] of Object.entries(message)) {
1601
+ if (key === `type` && value === `v2`) continue;
1602
+ processedMsg[key] = deserializeValue(value);
1603
+ }
1604
+ return processedMsg;
1605
+ });
1606
+ const paginatedCount = paginatedMessages.length;
1607
+ let countQuery = `SELECT count() as count FROM ${fullTableName} WHERE thread_id IN (${threadPlaceholders})`;
1608
+ const countParams = [...threadIds];
1609
+ if (resourceId) {
1610
+ countQuery += ` AND resourceId = ?`;
1611
+ countParams.push(resourceId);
1612
+ }
1613
+ if (dateRange?.start) {
1614
+ const startDate = dateRange.start instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.start) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.start));
1615
+ const startOp = dateRange.startExclusive ? ">" : ">=";
1616
+ countQuery += ` AND createdAt ${startOp} ?`;
1617
+ countParams.push(startDate);
1618
+ }
1619
+ if (dateRange?.end) {
1620
+ const endDate = dateRange.end instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.end) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.end));
1621
+ const endOp = dateRange.endExclusive ? "<" : "<=";
1622
+ countQuery += ` AND createdAt ${endOp} ?`;
1623
+ countParams.push(endDate);
1624
+ }
1625
+ const countMetadataConditions = [];
1626
+ addSqliteMetadataFilter(countMetadataConditions, countParams, metadataFilter);
1627
+ if (countMetadataConditions.length > 0) countQuery += ` AND ${countMetadataConditions.join(" AND ")}`;
1628
+ const countResult = await this.#db.executeQuery({
1629
+ sql: countQuery,
1630
+ params: countParams
1631
+ });
1632
+ const total = Number(countResult[0]?.count ?? 0);
1633
+ if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) return {
1634
+ messages: [],
1635
+ total: 0,
1636
+ page,
1637
+ perPage: perPageForResponse,
1638
+ hasMore: false
1639
+ };
1640
+ const messageIds = new Set(paginatedMessages.map((m) => m.id));
1641
+ let includeMessages = [];
1642
+ if (include && include.length > 0) {
1643
+ const includeResult = await this._getIncludedMessages(include);
1644
+ if (Array.isArray(includeResult)) {
1645
+ includeMessages = includeResult;
1646
+ for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
1647
+ paginatedMessages.push(includeMsg);
1648
+ messageIds.add(includeMsg.id);
1649
+ }
1650
+ }
1651
+ }
1652
+ const list = new _mastra_core_agent.MessageList().add(paginatedMessages, "memory");
1653
+ const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
1654
+ const threadIdSet = new Set(threadIds);
1655
+ const allThreadMessagesReturned = new Set(finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)).size >= total;
1656
+ return {
1657
+ messages: finalMessages,
1658
+ total,
1659
+ page,
1660
+ perPage: perPageForResponse,
1661
+ hasMore: metadataFilter ? perPageInput !== false && offset + paginatedCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total
1662
+ };
1663
+ } catch (error) {
1664
+ const mastraError = new _mastra_core_error.MastraError({
1665
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "FAILED"),
1666
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1667
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1668
+ text: `Failed to list messages for thread ${Array.isArray(threadId) ? threadId.join(",") : threadId}: ${error instanceof Error ? error.message : String(error)}`,
1669
+ details: {
1670
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1671
+ resourceId: resourceId ?? ""
1672
+ }
1673
+ }, error);
1674
+ this.logger?.error?.(mastraError.toString());
1675
+ this.logger?.trackException?.(mastraError);
1676
+ return {
1677
+ messages: [],
1678
+ total: 0,
1679
+ page,
1680
+ perPage: perPageForResponse,
1681
+ hasMore: false
1682
+ };
1683
+ }
1684
+ }
1685
+ async updateMessages(args) {
1686
+ const { messages } = args;
1687
+ this.logger.debug("Updating messages", { count: messages.length });
1688
+ if (!messages.length) return [];
1689
+ const messageIds = messages.map((m) => m.id);
1690
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1691
+ const threadsTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1692
+ try {
1693
+ const selectQuery = `SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId FROM ${fullTableName} WHERE id IN (${messageIds.map(() => "?").join(",")})`;
1694
+ const existingMessages = await this.#db.executeQuery({
1695
+ sql: selectQuery,
1696
+ params: messageIds
1697
+ });
1698
+ if (existingMessages.length === 0) return [];
1699
+ const parsedExistingMessages = existingMessages.map((msg) => {
1700
+ if (typeof msg.content === "string") try {
1701
+ msg.content = JSON.parse(msg.content);
1702
+ } catch {}
1703
+ return msg;
1704
+ });
1705
+ const threadIdsToUpdate = /* @__PURE__ */ new Set();
1706
+ const updateQueries = [];
1707
+ for (const existingMessage of parsedExistingMessages) {
1708
+ const updatePayload = messages.find((m) => m.id === existingMessage.id);
1709
+ if (!updatePayload) continue;
1710
+ const { id, ...fieldsToUpdate } = updatePayload;
1711
+ if (Object.keys(fieldsToUpdate).length === 0) continue;
1712
+ threadIdsToUpdate.add(existingMessage.threadId);
1713
+ if ("threadId" in updatePayload && updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) threadIdsToUpdate.add(updatePayload.threadId);
1714
+ const setClauses = [];
1715
+ const values = [];
1716
+ const updatableFields = { ...fieldsToUpdate };
1717
+ if (updatableFields.content) {
1718
+ const existingContent = existingMessage.content || {};
1719
+ const newContent = {
1720
+ ...existingContent,
1721
+ ...updatableFields.content,
1722
+ ...existingContent?.metadata && updatableFields.content.metadata ? { metadata: {
1723
+ ...existingContent.metadata,
1724
+ ...updatableFields.content.metadata
1725
+ } } : {}
1726
+ };
1727
+ setClauses.push(`content = ?`);
1728
+ values.push(JSON.stringify(newContent));
1729
+ delete updatableFields.content;
1730
+ }
1731
+ for (const key in updatableFields) if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
1732
+ const dbColumn = key === "threadId" ? "thread_id" : key;
1733
+ setClauses.push(`${dbColumn} = ?`);
1734
+ values.push(updatableFields[key]);
1735
+ }
1736
+ if (setClauses.length > 0) {
1737
+ values.push(id);
1738
+ const updateQuery = `UPDATE ${fullTableName} SET ${setClauses.join(", ")} WHERE id = ?`;
1739
+ updateQueries.push({
1740
+ sql: updateQuery,
1741
+ params: values
1742
+ });
1743
+ }
1744
+ }
1745
+ for (const query of updateQueries) await this.#db.executeQuery(query);
1746
+ if (threadIdsToUpdate.size > 0) {
1747
+ const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${Array.from(threadIdsToUpdate).map(() => "?").join(",")})`;
1748
+ const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...Array.from(threadIdsToUpdate)];
1749
+ await this.#db.executeQuery({
1750
+ sql: threadUpdateQuery,
1751
+ params: threadUpdateParams
1752
+ });
1753
+ }
1754
+ return (await this.#db.executeQuery({
1755
+ sql: selectQuery,
1756
+ params: messageIds
1757
+ })).map((message) => {
1758
+ if (typeof message.content === "string") try {
1759
+ message.content = JSON.parse(message.content);
1760
+ } catch {}
1761
+ return message;
1762
+ });
1763
+ } catch (error) {
1764
+ throw new _mastra_core_error.MastraError({
1765
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_MESSAGES", "FAILED"),
1766
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1767
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1768
+ details: { count: messages.length }
1769
+ }, error);
1770
+ }
1771
+ }
1772
+ async deleteMessages(messageIds) {
1773
+ if (messageIds.length === 0) return;
1774
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
1775
+ const threadsTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
1776
+ try {
1777
+ const placeholders = messageIds.map(() => "?").join(",");
1778
+ const selectQuery = `SELECT DISTINCT thread_id FROM ${fullTableName} WHERE id IN (${placeholders})`;
1779
+ const threadIds = (await this.#db.executeQuery({
1780
+ sql: selectQuery,
1781
+ params: messageIds
1782
+ })).map((r) => r.thread_id).filter(Boolean);
1783
+ const { sql, params } = createSqlBuilder().delete(fullTableName).where(`id IN (${placeholders})`, ...messageIds).build();
1784
+ await this.#db.executeQuery({
1785
+ sql,
1786
+ params
1787
+ });
1788
+ if (threadIds.length > 0) {
1789
+ const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${threadIds.map(() => "?").join(",")})`;
1790
+ const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...threadIds];
1791
+ await this.#db.executeQuery({
1792
+ sql: threadUpdateQuery,
1793
+ params: threadUpdateParams
1794
+ });
1795
+ }
1796
+ } catch (error) {
1797
+ throw new _mastra_core_error.MastraError({
1798
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_MESSAGES", "FAILED"),
1799
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1800
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1801
+ details: { messageIds: JSON.stringify(messageIds) }
1802
+ }, error);
1803
+ }
1804
+ }
1873
1805
  };
1806
+ //#endregion
1807
+ //#region src/storage/domains/scores/index.ts
1808
+ /** Applies multi-tenant scope conditions to a query builder. */
1874
1809
  function applyTenancyFilters(query, filters) {
1875
- if (filters?.organizationId !== void 0) {
1876
- query.andWhere("organizationId = ?", filters.organizationId);
1877
- }
1878
- if (filters?.projectId !== void 0) {
1879
- query.andWhere("projectId = ?", filters.projectId);
1880
- }
1810
+ if (filters?.organizationId !== void 0) query.andWhere("organizationId = ?", filters.organizationId);
1811
+ if (filters?.projectId !== void 0) query.andWhere("projectId = ?", filters.projectId);
1881
1812
  }
1813
+ /**
1814
+ * Cloudflare D1-specific score row transformation.
1815
+ * Uses Z-suffix timestamps (createdAtZ, updatedAtZ) when available.
1816
+ */
1882
1817
  function transformScoreRow(row) {
1883
- return storage.transformScoreRow(row, {
1884
- preferredTimestampFields: {
1885
- createdAt: "createdAtZ",
1886
- updatedAt: "updatedAtZ"
1887
- }
1888
- });
1818
+ return (0, _mastra_core_storage.transformScoreRow)(row, { preferredTimestampFields: {
1819
+ createdAt: "createdAtZ",
1820
+ updatedAt: "updatedAtZ"
1821
+ } });
1889
1822
  }
1890
- var ScoresStorageD1 = class extends storage.ScoresStorage {
1891
- #db;
1892
- constructor(config) {
1893
- super();
1894
- this.#db = new D1DB(resolveD1Config(config));
1895
- }
1896
- async init() {
1897
- await this.#db.createTable({ tableName: storage.TABLE_SCORERS, schema: storage.TABLE_SCHEMAS[storage.TABLE_SCORERS] });
1898
- await this.#db.alterTable({
1899
- tableName: storage.TABLE_SCORERS,
1900
- schema: storage.TABLE_SCHEMAS[storage.TABLE_SCORERS],
1901
- ifNotExists: ["organizationId", "projectId", "batchId", "datasetId", "datasetItemId"]
1902
- });
1903
- }
1904
- async dangerouslyClearAll() {
1905
- await this.#db.clearTable({ tableName: storage.TABLE_SCORERS });
1906
- }
1907
- async getScoreById({ id }) {
1908
- try {
1909
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
1910
- const query = createSqlBuilder().select("*").from(fullTableName).where("id = ?", id);
1911
- const { sql, params } = query.build();
1912
- const result = await this.#db.executeQuery({ sql, params, first: true });
1913
- if (!result) {
1914
- return null;
1915
- }
1916
- return transformScoreRow(result);
1917
- } catch (error$1) {
1918
- throw new error.MastraError(
1919
- {
1920
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORE_BY_ID", "FAILED"),
1921
- domain: error.ErrorDomain.STORAGE,
1922
- category: error.ErrorCategory.THIRD_PARTY
1923
- },
1924
- error$1
1925
- );
1926
- }
1927
- }
1928
- async saveScore(score) {
1929
- let parsedScore;
1930
- try {
1931
- parsedScore = evals.saveScorePayloadSchema.parse(score);
1932
- } catch (error$1) {
1933
- throw new error.MastraError(
1934
- {
1935
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "SAVE_SCORE", "VALIDATION_FAILED"),
1936
- domain: error.ErrorDomain.STORAGE,
1937
- category: error.ErrorCategory.USER,
1938
- details: {
1939
- scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
1940
- entityId: score.entityId ?? "unknown",
1941
- entityType: score.entityType ?? "unknown",
1942
- traceId: score.traceId ?? "",
1943
- spanId: score.spanId ?? ""
1944
- }
1945
- },
1946
- error$1
1947
- );
1948
- }
1949
- const id = crypto.randomUUID();
1950
- try {
1951
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
1952
- const serializedRecord = {};
1953
- for (const [key, value] of Object.entries(parsedScore)) {
1954
- if (value !== null && value !== void 0) {
1955
- if (typeof value === "object") {
1956
- serializedRecord[key] = JSON.stringify(value);
1957
- } else {
1958
- serializedRecord[key] = value;
1959
- }
1960
- } else {
1961
- serializedRecord[key] = null;
1962
- }
1963
- }
1964
- const now = /* @__PURE__ */ new Date();
1965
- serializedRecord.id = id;
1966
- serializedRecord.createdAt = now.toISOString();
1967
- serializedRecord.updatedAt = now.toISOString();
1968
- const columns = Object.keys(serializedRecord);
1969
- const values = Object.values(serializedRecord);
1970
- const query = createSqlBuilder().insert(fullTableName, columns, values);
1971
- const { sql, params } = query.build();
1972
- await this.#db.executeQuery({ sql, params });
1973
- return { score: { ...parsedScore, id, createdAt: now, updatedAt: now } };
1974
- } catch (error$1) {
1975
- throw new error.MastraError(
1976
- {
1977
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "SAVE_SCORE", "FAILED"),
1978
- domain: error.ErrorDomain.STORAGE,
1979
- category: error.ErrorCategory.THIRD_PARTY,
1980
- details: { id }
1981
- },
1982
- error$1
1983
- );
1984
- }
1985
- }
1986
- async listScoresByScorerId({
1987
- scorerId,
1988
- entityId,
1989
- entityType,
1990
- source,
1991
- pagination,
1992
- filters
1993
- }) {
1994
- try {
1995
- const { page, perPage: perPageInput } = pagination;
1996
- const perPage = storage.normalizePerPage(perPageInput, 100);
1997
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1998
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
1999
- const countQuery = createSqlBuilder().count().from(fullTableName).where("scorerId = ?", scorerId);
2000
- if (entityId) {
2001
- countQuery.andWhere("entityId = ?", entityId);
2002
- }
2003
- if (entityType) {
2004
- countQuery.andWhere("entityType = ?", entityType);
2005
- }
2006
- if (source) {
2007
- countQuery.andWhere("source = ?", source);
2008
- }
2009
- applyTenancyFilters(countQuery, filters);
2010
- const countResult = await this.#db.executeQuery(countQuery.build());
2011
- const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2012
- if (total === 0) {
2013
- return {
2014
- pagination: {
2015
- total: 0,
2016
- page,
2017
- perPage: perPageForResponse,
2018
- hasMore: false
2019
- },
2020
- scores: []
2021
- };
2022
- }
2023
- const end = perPageInput === false ? total : start + perPage;
2024
- const limitValue = perPageInput === false ? total : perPage;
2025
- const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("scorerId = ?", scorerId);
2026
- if (entityId) {
2027
- selectQuery.andWhere("entityId = ?", entityId);
2028
- }
2029
- if (entityType) {
2030
- selectQuery.andWhere("entityType = ?", entityType);
2031
- }
2032
- if (source) {
2033
- selectQuery.andWhere("source = ?", source);
2034
- }
2035
- applyTenancyFilters(selectQuery, filters);
2036
- selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2037
- const { sql, params } = selectQuery.build();
2038
- const results = await this.#db.executeQuery({ sql, params });
2039
- const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2040
- return {
2041
- pagination: {
2042
- total,
2043
- page,
2044
- perPage: perPageForResponse,
2045
- hasMore: end < total
2046
- },
2047
- scores
2048
- };
2049
- } catch (error$1) {
2050
- throw new error.MastraError(
2051
- {
2052
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORES_BY_SCORER_ID", "FAILED"),
2053
- domain: error.ErrorDomain.STORAGE,
2054
- category: error.ErrorCategory.THIRD_PARTY
2055
- },
2056
- error$1
2057
- );
2058
- }
2059
- }
2060
- async listScoresByRunId({
2061
- runId,
2062
- pagination,
2063
- filters
2064
- }) {
2065
- try {
2066
- const { page, perPage: perPageInput } = pagination;
2067
- const perPage = storage.normalizePerPage(perPageInput, 100);
2068
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2069
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
2070
- const countQuery = createSqlBuilder().count().from(fullTableName).where("runId = ?", runId);
2071
- applyTenancyFilters(countQuery, filters);
2072
- const countResult = await this.#db.executeQuery(countQuery.build());
2073
- const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2074
- if (total === 0) {
2075
- return {
2076
- pagination: {
2077
- total: 0,
2078
- page,
2079
- perPage: perPageForResponse,
2080
- hasMore: false
2081
- },
2082
- scores: []
2083
- };
2084
- }
2085
- const end = perPageInput === false ? total : start + perPage;
2086
- const limitValue = perPageInput === false ? total : perPage;
2087
- const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("runId = ?", runId);
2088
- applyTenancyFilters(selectQuery, filters);
2089
- selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2090
- const { sql, params } = selectQuery.build();
2091
- const results = await this.#db.executeQuery({ sql, params });
2092
- const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2093
- return {
2094
- pagination: {
2095
- total,
2096
- page,
2097
- perPage: perPageForResponse,
2098
- hasMore: end < total
2099
- },
2100
- scores
2101
- };
2102
- } catch (error$1) {
2103
- throw new error.MastraError(
2104
- {
2105
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORES_BY_RUN_ID", "FAILED"),
2106
- domain: error.ErrorDomain.STORAGE,
2107
- category: error.ErrorCategory.THIRD_PARTY
2108
- },
2109
- error$1
2110
- );
2111
- }
2112
- }
2113
- async listScoresByEntityId({
2114
- entityId,
2115
- entityType,
2116
- pagination,
2117
- filters
2118
- }) {
2119
- try {
2120
- const { page, perPage: perPageInput } = pagination;
2121
- const perPage = storage.normalizePerPage(perPageInput, 100);
2122
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2123
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
2124
- const countQuery = createSqlBuilder().count().from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
2125
- applyTenancyFilters(countQuery, filters);
2126
- const countResult = await this.#db.executeQuery(countQuery.build());
2127
- const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2128
- if (total === 0) {
2129
- return {
2130
- pagination: {
2131
- total: 0,
2132
- page,
2133
- perPage: perPageForResponse,
2134
- hasMore: false
2135
- },
2136
- scores: []
2137
- };
2138
- }
2139
- const end = perPageInput === false ? total : start + perPage;
2140
- const limitValue = perPageInput === false ? total : perPage;
2141
- const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
2142
- applyTenancyFilters(selectQuery, filters);
2143
- selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2144
- const { sql, params } = selectQuery.build();
2145
- const results = await this.#db.executeQuery({ sql, params });
2146
- const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2147
- return {
2148
- pagination: {
2149
- total,
2150
- page,
2151
- perPage: perPageForResponse,
2152
- hasMore: end < total
2153
- },
2154
- scores
2155
- };
2156
- } catch (error$1) {
2157
- throw new error.MastraError(
2158
- {
2159
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORES_BY_ENTITY_ID", "FAILED"),
2160
- domain: error.ErrorDomain.STORAGE,
2161
- category: error.ErrorCategory.THIRD_PARTY
2162
- },
2163
- error$1
2164
- );
2165
- }
2166
- }
2167
- async listScoresBySpan({
2168
- traceId,
2169
- spanId,
2170
- pagination,
2171
- filters
2172
- }) {
2173
- try {
2174
- const { page, perPage: perPageInput } = pagination;
2175
- const perPage = storage.normalizePerPage(perPageInput, 100);
2176
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2177
- const fullTableName = this.#db.getTableName(storage.TABLE_SCORERS);
2178
- const countQuery = createSqlBuilder().count().from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
2179
- applyTenancyFilters(countQuery, filters);
2180
- const countResult = await this.#db.executeQuery(countQuery.build());
2181
- const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2182
- if (total === 0) {
2183
- return {
2184
- pagination: {
2185
- total: 0,
2186
- page,
2187
- perPage: perPageForResponse,
2188
- hasMore: false
2189
- },
2190
- scores: []
2191
- };
2192
- }
2193
- const end = perPageInput === false ? total : start + perPage;
2194
- const limitValue = perPageInput === false ? total : perPage;
2195
- const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
2196
- applyTenancyFilters(selectQuery, filters);
2197
- selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2198
- const { sql, params } = selectQuery.build();
2199
- const results = await this.#db.executeQuery({ sql, params });
2200
- const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2201
- return {
2202
- pagination: {
2203
- total,
2204
- page,
2205
- perPage: perPageForResponse,
2206
- hasMore: end < total
2207
- },
2208
- scores
2209
- };
2210
- } catch (error$1) {
2211
- throw new error.MastraError(
2212
- {
2213
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORES_BY_SPAN", "FAILED"),
2214
- domain: error.ErrorDomain.STORAGE,
2215
- category: error.ErrorCategory.THIRD_PARTY
2216
- },
2217
- error$1
2218
- );
2219
- }
2220
- }
1823
+ var ScoresStorageD1 = class extends _mastra_core_storage.ScoresStorage {
1824
+ #db;
1825
+ constructor(config) {
1826
+ super();
1827
+ this.#db = new D1DB(resolveD1Config(config));
1828
+ }
1829
+ async init() {
1830
+ await this.#db.createTable({
1831
+ tableName: _mastra_core_storage.TABLE_SCORERS,
1832
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_SCORERS]
1833
+ });
1834
+ await this.#db.alterTable({
1835
+ tableName: _mastra_core_storage.TABLE_SCORERS,
1836
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_SCORERS],
1837
+ ifNotExists: [
1838
+ "organizationId",
1839
+ "projectId",
1840
+ "batchId",
1841
+ "datasetId",
1842
+ "datasetItemId"
1843
+ ]
1844
+ });
1845
+ }
1846
+ async dangerouslyClearAll() {
1847
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_SCORERS });
1848
+ }
1849
+ async getScoreById({ id }) {
1850
+ try {
1851
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
1852
+ const { sql, params } = createSqlBuilder().select("*").from(fullTableName).where("id = ?", id).build();
1853
+ const result = await this.#db.executeQuery({
1854
+ sql,
1855
+ params,
1856
+ first: true
1857
+ });
1858
+ if (!result) return null;
1859
+ return transformScoreRow(result);
1860
+ } catch (error) {
1861
+ throw new _mastra_core_error.MastraError({
1862
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORE_BY_ID", "FAILED"),
1863
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1864
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
1865
+ }, error);
1866
+ }
1867
+ }
1868
+ async saveScore(score) {
1869
+ let parsedScore;
1870
+ try {
1871
+ parsedScore = _mastra_core_evals.saveScorePayloadSchema.parse(score);
1872
+ } catch (error) {
1873
+ throw new _mastra_core_error.MastraError({
1874
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_SCORE", "VALIDATION_FAILED"),
1875
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1876
+ category: _mastra_core_error.ErrorCategory.USER,
1877
+ details: {
1878
+ scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
1879
+ entityId: score.entityId ?? "unknown",
1880
+ entityType: score.entityType ?? "unknown",
1881
+ traceId: score.traceId ?? "",
1882
+ spanId: score.spanId ?? ""
1883
+ }
1884
+ }, error);
1885
+ }
1886
+ const id = crypto.randomUUID();
1887
+ try {
1888
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
1889
+ const serializedRecord = {};
1890
+ for (const [key, value] of Object.entries(parsedScore)) if (value !== null && value !== void 0) if (typeof value === "object") serializedRecord[key] = JSON.stringify(value);
1891
+ else serializedRecord[key] = value;
1892
+ else serializedRecord[key] = null;
1893
+ const now = /* @__PURE__ */ new Date();
1894
+ serializedRecord.id = id;
1895
+ serializedRecord.createdAt = now.toISOString();
1896
+ serializedRecord.updatedAt = now.toISOString();
1897
+ const columns = Object.keys(serializedRecord);
1898
+ const values = Object.values(serializedRecord);
1899
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
1900
+ await this.#db.executeQuery({
1901
+ sql,
1902
+ params
1903
+ });
1904
+ return { score: {
1905
+ ...parsedScore,
1906
+ id,
1907
+ createdAt: now,
1908
+ updatedAt: now
1909
+ } };
1910
+ } catch (error) {
1911
+ throw new _mastra_core_error.MastraError({
1912
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_SCORE", "FAILED"),
1913
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1914
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
1915
+ details: { id }
1916
+ }, error);
1917
+ }
1918
+ }
1919
+ async listScoresByScorerId({ scorerId, entityId, entityType, source, pagination, filters }) {
1920
+ try {
1921
+ const { page, perPage: perPageInput } = pagination;
1922
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
1923
+ const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
1924
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
1925
+ const countQuery = createSqlBuilder().count().from(fullTableName).where("scorerId = ?", scorerId);
1926
+ if (entityId) countQuery.andWhere("entityId = ?", entityId);
1927
+ if (entityType) countQuery.andWhere("entityType = ?", entityType);
1928
+ if (source) countQuery.andWhere("source = ?", source);
1929
+ applyTenancyFilters(countQuery, filters);
1930
+ const countResult = await this.#db.executeQuery(countQuery.build());
1931
+ const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
1932
+ if (total === 0) return {
1933
+ pagination: {
1934
+ total: 0,
1935
+ page,
1936
+ perPage: perPageForResponse,
1937
+ hasMore: false
1938
+ },
1939
+ scores: []
1940
+ };
1941
+ const end = perPageInput === false ? total : start + perPage;
1942
+ const limitValue = perPageInput === false ? total : perPage;
1943
+ const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("scorerId = ?", scorerId);
1944
+ if (entityId) selectQuery.andWhere("entityId = ?", entityId);
1945
+ if (entityType) selectQuery.andWhere("entityType = ?", entityType);
1946
+ if (source) selectQuery.andWhere("source = ?", source);
1947
+ applyTenancyFilters(selectQuery, filters);
1948
+ selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
1949
+ const { sql, params } = selectQuery.build();
1950
+ const results = await this.#db.executeQuery({
1951
+ sql,
1952
+ params
1953
+ });
1954
+ const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
1955
+ return {
1956
+ pagination: {
1957
+ total,
1958
+ page,
1959
+ perPage: perPageForResponse,
1960
+ hasMore: end < total
1961
+ },
1962
+ scores
1963
+ };
1964
+ } catch (error) {
1965
+ throw new _mastra_core_error.MastraError({
1966
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_SCORER_ID", "FAILED"),
1967
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
1968
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
1969
+ }, error);
1970
+ }
1971
+ }
1972
+ async listScoresByRunId({ runId, pagination, filters }) {
1973
+ try {
1974
+ const { page, perPage: perPageInput } = pagination;
1975
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
1976
+ const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
1977
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
1978
+ const countQuery = createSqlBuilder().count().from(fullTableName).where("runId = ?", runId);
1979
+ applyTenancyFilters(countQuery, filters);
1980
+ const countResult = await this.#db.executeQuery(countQuery.build());
1981
+ const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
1982
+ if (total === 0) return {
1983
+ pagination: {
1984
+ total: 0,
1985
+ page,
1986
+ perPage: perPageForResponse,
1987
+ hasMore: false
1988
+ },
1989
+ scores: []
1990
+ };
1991
+ const end = perPageInput === false ? total : start + perPage;
1992
+ const limitValue = perPageInput === false ? total : perPage;
1993
+ const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("runId = ?", runId);
1994
+ applyTenancyFilters(selectQuery, filters);
1995
+ selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
1996
+ const { sql, params } = selectQuery.build();
1997
+ const results = await this.#db.executeQuery({
1998
+ sql,
1999
+ params
2000
+ });
2001
+ const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2002
+ return {
2003
+ pagination: {
2004
+ total,
2005
+ page,
2006
+ perPage: perPageForResponse,
2007
+ hasMore: end < total
2008
+ },
2009
+ scores
2010
+ };
2011
+ } catch (error) {
2012
+ throw new _mastra_core_error.MastraError({
2013
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_RUN_ID", "FAILED"),
2014
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2015
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
2016
+ }, error);
2017
+ }
2018
+ }
2019
+ async listScoresByEntityId({ entityId, entityType, pagination, filters }) {
2020
+ try {
2021
+ const { page, perPage: perPageInput } = pagination;
2022
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
2023
+ const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
2024
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
2025
+ const countQuery = createSqlBuilder().count().from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
2026
+ applyTenancyFilters(countQuery, filters);
2027
+ const countResult = await this.#db.executeQuery(countQuery.build());
2028
+ const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2029
+ if (total === 0) return {
2030
+ pagination: {
2031
+ total: 0,
2032
+ page,
2033
+ perPage: perPageForResponse,
2034
+ hasMore: false
2035
+ },
2036
+ scores: []
2037
+ };
2038
+ const end = perPageInput === false ? total : start + perPage;
2039
+ const limitValue = perPageInput === false ? total : perPage;
2040
+ const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
2041
+ applyTenancyFilters(selectQuery, filters);
2042
+ selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2043
+ const { sql, params } = selectQuery.build();
2044
+ const results = await this.#db.executeQuery({
2045
+ sql,
2046
+ params
2047
+ });
2048
+ const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2049
+ return {
2050
+ pagination: {
2051
+ total,
2052
+ page,
2053
+ perPage: perPageForResponse,
2054
+ hasMore: end < total
2055
+ },
2056
+ scores
2057
+ };
2058
+ } catch (error) {
2059
+ throw new _mastra_core_error.MastraError({
2060
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_ENTITY_ID", "FAILED"),
2061
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2062
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
2063
+ }, error);
2064
+ }
2065
+ }
2066
+ async listScoresBySpan({ traceId, spanId, pagination, filters }) {
2067
+ try {
2068
+ const { page, perPage: perPageInput } = pagination;
2069
+ const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
2070
+ const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
2071
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
2072
+ const countQuery = createSqlBuilder().count().from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
2073
+ applyTenancyFilters(countQuery, filters);
2074
+ const countResult = await this.#db.executeQuery(countQuery.build());
2075
+ const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
2076
+ if (total === 0) return {
2077
+ pagination: {
2078
+ total: 0,
2079
+ page,
2080
+ perPage: perPageForResponse,
2081
+ hasMore: false
2082
+ },
2083
+ scores: []
2084
+ };
2085
+ const end = perPageInput === false ? total : start + perPage;
2086
+ const limitValue = perPageInput === false ? total : perPage;
2087
+ const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
2088
+ applyTenancyFilters(selectQuery, filters);
2089
+ selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
2090
+ const { sql, params } = selectQuery.build();
2091
+ const results = await this.#db.executeQuery({
2092
+ sql,
2093
+ params
2094
+ });
2095
+ const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
2096
+ return {
2097
+ pagination: {
2098
+ total,
2099
+ page,
2100
+ perPage: perPageForResponse,
2101
+ hasMore: end < total
2102
+ },
2103
+ scores
2104
+ };
2105
+ } catch (error) {
2106
+ throw new _mastra_core_error.MastraError({
2107
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_SPAN", "FAILED"),
2108
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2109
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
2110
+ }, error);
2111
+ }
2112
+ }
2221
2113
  };
2222
- var WorkflowsStorageD1 = class extends storage.WorkflowsStorage {
2223
- #db;
2224
- constructor(config) {
2225
- super();
2226
- this.#db = new D1DB(resolveD1Config(config));
2227
- }
2228
- supportsConcurrentUpdates() {
2229
- return false;
2230
- }
2231
- async init() {
2232
- await this.#db.createTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT] });
2233
- }
2234
- async dangerouslyClearAll() {
2235
- await this.#db.clearTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
2236
- }
2237
- async updateWorkflowResults(_args) {
2238
- throw new Error(
2239
- "updateWorkflowResults is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates."
2240
- );
2241
- }
2242
- async updateWorkflowState(_args) {
2243
- throw new Error(
2244
- "updateWorkflowState is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates."
2245
- );
2246
- }
2247
- async persistWorkflowSnapshot({
2248
- workflowName,
2249
- runId,
2250
- resourceId,
2251
- snapshot,
2252
- createdAt,
2253
- updatedAt
2254
- }) {
2255
- const fullTableName = this.#db.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
2256
- const now = (/* @__PURE__ */ new Date()).toISOString();
2257
- const currentSnapshot = await this.#db.load({
2258
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
2259
- keys: { workflow_name: workflowName, run_id: runId }
2260
- });
2261
- const persisting = currentSnapshot ? {
2262
- ...currentSnapshot,
2263
- resourceId,
2264
- snapshot: JSON.stringify(snapshot),
2265
- updatedAt: updatedAt ? updatedAt.toISOString() : now
2266
- } : {
2267
- workflow_name: workflowName,
2268
- run_id: runId,
2269
- resourceId,
2270
- snapshot,
2271
- createdAt: createdAt ? createdAt.toISOString() : now,
2272
- updatedAt: updatedAt ? updatedAt.toISOString() : now
2273
- };
2274
- const processedRecord = await this.#db.processRecord(persisting);
2275
- const columns = Object.keys(processedRecord);
2276
- const values = Object.values(processedRecord);
2277
- const updateMap = {
2278
- snapshot: "excluded.snapshot",
2279
- updatedAt: "excluded.updatedAt"
2280
- };
2281
- this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
2282
- const query = createSqlBuilder().insert(fullTableName, columns, values, ["workflow_name", "run_id"], updateMap);
2283
- const { sql, params } = query.build();
2284
- try {
2285
- await this.#db.executeQuery({ sql, params });
2286
- } catch (error$1) {
2287
- throw new error.MastraError(
2288
- {
2289
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
2290
- domain: error.ErrorDomain.STORAGE,
2291
- category: error.ErrorCategory.THIRD_PARTY,
2292
- text: `Failed to persist workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
2293
- details: { workflowName, runId }
2294
- },
2295
- error$1
2296
- );
2297
- }
2298
- }
2299
- async loadWorkflowSnapshot(params) {
2300
- const { workflowName, runId } = params;
2301
- this.logger.debug("Loading workflow snapshot", { workflowName, runId });
2302
- try {
2303
- const d = await this.#db.load({
2304
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
2305
- keys: {
2306
- workflow_name: workflowName,
2307
- run_id: runId
2308
- }
2309
- });
2310
- return d ? d.snapshot : null;
2311
- } catch (error$1) {
2312
- throw new error.MastraError(
2313
- {
2314
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
2315
- domain: error.ErrorDomain.STORAGE,
2316
- category: error.ErrorCategory.THIRD_PARTY,
2317
- text: `Failed to load workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
2318
- details: { workflowName, runId }
2319
- },
2320
- error$1
2321
- );
2322
- }
2323
- }
2324
- parseWorkflowRun(row) {
2325
- let parsedSnapshot = row.snapshot;
2326
- if (typeof parsedSnapshot === "string") {
2327
- try {
2328
- parsedSnapshot = JSON.parse(row.snapshot);
2329
- } catch (e) {
2330
- this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
2331
- }
2332
- }
2333
- return {
2334
- workflowName: row.workflow_name,
2335
- runId: row.run_id,
2336
- snapshot: parsedSnapshot,
2337
- createdAt: storage.ensureDate(row.createdAt),
2338
- updatedAt: storage.ensureDate(row.updatedAt),
2339
- resourceId: row.resourceId
2340
- };
2341
- }
2342
- async listWorkflowRuns({
2343
- workflowName,
2344
- fromDate,
2345
- toDate,
2346
- page,
2347
- perPage,
2348
- resourceId,
2349
- status
2350
- } = {}) {
2351
- const fullTableName = this.#db.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
2352
- try {
2353
- const builder = createSqlBuilder().select().from(fullTableName);
2354
- const countBuilder = createSqlBuilder().count().from(fullTableName);
2355
- if (workflowName) builder.whereAnd("workflow_name = ?", workflowName);
2356
- if (status) {
2357
- builder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
2358
- countBuilder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
2359
- }
2360
- if (resourceId) {
2361
- const hasResourceId = await this.#db.hasColumn(fullTableName, "resourceId");
2362
- if (hasResourceId) {
2363
- builder.whereAnd("resourceId = ?", resourceId);
2364
- countBuilder.whereAnd("resourceId = ?", resourceId);
2365
- } else {
2366
- this.logger.warn(`[${fullTableName}] resourceId column not found. Skipping resourceId filter.`);
2367
- }
2368
- }
2369
- if (fromDate) {
2370
- builder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
2371
- countBuilder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
2372
- }
2373
- if (toDate) {
2374
- builder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
2375
- countBuilder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
2376
- }
2377
- builder.orderBy("createdAt", "DESC");
2378
- if (typeof perPage === "number" && typeof page === "number") {
2379
- const offset = page * perPage;
2380
- builder.limit(perPage);
2381
- builder.offset(offset);
2382
- }
2383
- const { sql, params } = builder.build();
2384
- let total = 0;
2385
- if (perPage !== void 0 && page !== void 0) {
2386
- const { sql: countSql, params: countParams } = countBuilder.build();
2387
- const countResult = await this.#db.executeQuery({
2388
- sql: countSql,
2389
- params: countParams,
2390
- first: true
2391
- });
2392
- total = Number(countResult?.count ?? 0);
2393
- }
2394
- const results = await this.#db.executeQuery({ sql, params });
2395
- const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
2396
- return { runs, total: total || runs.length };
2397
- } catch (error$1) {
2398
- throw new error.MastraError(
2399
- {
2400
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_WORKFLOW_RUNS", "FAILED"),
2401
- domain: error.ErrorDomain.STORAGE,
2402
- category: error.ErrorCategory.THIRD_PARTY,
2403
- text: `Failed to retrieve workflow runs: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
2404
- details: {
2405
- workflowName: workflowName ?? "",
2406
- resourceId: resourceId ?? ""
2407
- }
2408
- },
2409
- error$1
2410
- );
2411
- }
2412
- }
2413
- async getWorkflowRunById({
2414
- runId,
2415
- workflowName
2416
- }) {
2417
- const fullTableName = this.#db.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
2418
- try {
2419
- const conditions = [];
2420
- const params = [];
2421
- if (runId) {
2422
- conditions.push("run_id = ?");
2423
- params.push(runId);
2424
- }
2425
- if (workflowName) {
2426
- conditions.push("workflow_name = ?");
2427
- params.push(workflowName);
2428
- }
2429
- const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
2430
- const sql = `SELECT * FROM ${fullTableName} ${whereClause} ORDER BY createdAt DESC LIMIT 1`;
2431
- const result = await this.#db.executeQuery({ sql, params, first: true });
2432
- if (!result) return null;
2433
- return this.parseWorkflowRun(result);
2434
- } catch (error$1) {
2435
- throw new error.MastraError(
2436
- {
2437
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
2438
- domain: error.ErrorDomain.STORAGE,
2439
- category: error.ErrorCategory.THIRD_PARTY,
2440
- text: `Failed to retrieve workflow run by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
2441
- details: { runId, workflowName: workflowName ?? "" }
2442
- },
2443
- error$1
2444
- );
2445
- }
2446
- }
2447
- async deleteWorkflowRunById({ runId, workflowName }) {
2448
- const fullTableName = this.#db.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
2449
- try {
2450
- const sql = `DELETE FROM ${fullTableName} WHERE workflow_name = ? AND run_id = ?`;
2451
- const params = [workflowName, runId];
2452
- await this.#db.executeQuery({ sql, params });
2453
- } catch (error$1) {
2454
- throw new error.MastraError(
2455
- {
2456
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
2457
- domain: error.ErrorDomain.STORAGE,
2458
- category: error.ErrorCategory.THIRD_PARTY,
2459
- text: `Failed to delete workflow run by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
2460
- details: { runId, workflowName }
2461
- },
2462
- error$1
2463
- );
2464
- }
2465
- }
2114
+ //#endregion
2115
+ //#region src/storage/domains/workflows/index.ts
2116
+ var WorkflowsStorageD1 = class extends _mastra_core_storage.WorkflowsStorage {
2117
+ #db;
2118
+ constructor(config) {
2119
+ super();
2120
+ this.#db = new D1DB(resolveD1Config(config));
2121
+ }
2122
+ supportsConcurrentUpdates() {
2123
+ return false;
2124
+ }
2125
+ async init() {
2126
+ await this.#db.createTable({
2127
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
2128
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT]
2129
+ });
2130
+ }
2131
+ async dangerouslyClearAll() {
2132
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT });
2133
+ }
2134
+ async updateWorkflowResults(_args) {
2135
+ throw new Error("updateWorkflowResults is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates.");
2136
+ }
2137
+ async updateWorkflowState(_args) {
2138
+ throw new Error("updateWorkflowState is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates.");
2139
+ }
2140
+ async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt }) {
2141
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
2142
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2143
+ const currentSnapshot = await this.#db.load({
2144
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
2145
+ keys: {
2146
+ workflow_name: workflowName,
2147
+ run_id: runId
2148
+ }
2149
+ });
2150
+ const persisting = currentSnapshot ? {
2151
+ ...currentSnapshot,
2152
+ resourceId,
2153
+ snapshot: JSON.stringify(snapshot),
2154
+ updatedAt: updatedAt ? updatedAt.toISOString() : now
2155
+ } : {
2156
+ workflow_name: workflowName,
2157
+ run_id: runId,
2158
+ resourceId,
2159
+ snapshot,
2160
+ createdAt: createdAt ? createdAt.toISOString() : now,
2161
+ updatedAt: updatedAt ? updatedAt.toISOString() : now
2162
+ };
2163
+ const processedRecord = await this.#db.processRecord(persisting);
2164
+ const columns = Object.keys(processedRecord);
2165
+ const values = Object.values(processedRecord);
2166
+ const updateMap = {
2167
+ snapshot: "excluded.snapshot",
2168
+ updatedAt: "excluded.updatedAt"
2169
+ };
2170
+ this.logger.debug("Persisting workflow snapshot", {
2171
+ workflowName,
2172
+ runId
2173
+ });
2174
+ const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["workflow_name", "run_id"], updateMap).build();
2175
+ try {
2176
+ await this.#db.executeQuery({
2177
+ sql,
2178
+ params
2179
+ });
2180
+ } catch (error) {
2181
+ throw new _mastra_core_error.MastraError({
2182
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
2183
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2184
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
2185
+ text: `Failed to persist workflow snapshot: ${error instanceof Error ? error.message : String(error)}`,
2186
+ details: {
2187
+ workflowName,
2188
+ runId
2189
+ }
2190
+ }, error);
2191
+ }
2192
+ }
2193
+ async loadWorkflowSnapshot(params) {
2194
+ const { workflowName, runId } = params;
2195
+ this.logger.debug("Loading workflow snapshot", {
2196
+ workflowName,
2197
+ runId
2198
+ });
2199
+ try {
2200
+ const d = await this.#db.load({
2201
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
2202
+ keys: {
2203
+ workflow_name: workflowName,
2204
+ run_id: runId
2205
+ }
2206
+ });
2207
+ return d ? d.snapshot : null;
2208
+ } catch (error) {
2209
+ throw new _mastra_core_error.MastraError({
2210
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
2211
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2212
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
2213
+ text: `Failed to load workflow snapshot: ${error instanceof Error ? error.message : String(error)}`,
2214
+ details: {
2215
+ workflowName,
2216
+ runId
2217
+ }
2218
+ }, error);
2219
+ }
2220
+ }
2221
+ parseWorkflowRun(row) {
2222
+ let parsedSnapshot = row.snapshot;
2223
+ if (typeof parsedSnapshot === "string") try {
2224
+ parsedSnapshot = JSON.parse(row.snapshot);
2225
+ } catch (e) {
2226
+ this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
2227
+ }
2228
+ return {
2229
+ workflowName: row.workflow_name,
2230
+ runId: row.run_id,
2231
+ snapshot: parsedSnapshot,
2232
+ createdAt: (0, _mastra_core_storage.ensureDate)(row.createdAt),
2233
+ updatedAt: (0, _mastra_core_storage.ensureDate)(row.updatedAt),
2234
+ resourceId: row.resourceId
2235
+ };
2236
+ }
2237
+ async listWorkflowRuns({ workflowName, fromDate, toDate, page, perPage, resourceId, status } = {}) {
2238
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
2239
+ try {
2240
+ const builder = createSqlBuilder().select().from(fullTableName);
2241
+ const countBuilder = createSqlBuilder().count().from(fullTableName);
2242
+ if (workflowName) builder.whereAnd("workflow_name = ?", workflowName);
2243
+ if (status) {
2244
+ builder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
2245
+ countBuilder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
2246
+ }
2247
+ if (resourceId) if (await this.#db.hasColumn(fullTableName, "resourceId")) {
2248
+ builder.whereAnd("resourceId = ?", resourceId);
2249
+ countBuilder.whereAnd("resourceId = ?", resourceId);
2250
+ } else this.logger.warn(`[${fullTableName}] resourceId column not found. Skipping resourceId filter.`);
2251
+ if (fromDate) {
2252
+ builder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
2253
+ countBuilder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
2254
+ }
2255
+ if (toDate) {
2256
+ builder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
2257
+ countBuilder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
2258
+ }
2259
+ builder.orderBy("createdAt", "DESC");
2260
+ if (typeof perPage === "number" && typeof page === "number") {
2261
+ const offset = page * perPage;
2262
+ builder.limit(perPage);
2263
+ builder.offset(offset);
2264
+ }
2265
+ const { sql, params } = builder.build();
2266
+ let total = 0;
2267
+ if (perPage !== void 0 && page !== void 0) {
2268
+ const { sql: countSql, params: countParams } = countBuilder.build();
2269
+ const countResult = await this.#db.executeQuery({
2270
+ sql: countSql,
2271
+ params: countParams,
2272
+ first: true
2273
+ });
2274
+ total = Number(countResult?.count ?? 0);
2275
+ }
2276
+ const results = await this.#db.executeQuery({
2277
+ sql,
2278
+ params
2279
+ });
2280
+ const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
2281
+ return {
2282
+ runs,
2283
+ total: total || runs.length
2284
+ };
2285
+ } catch (error) {
2286
+ throw new _mastra_core_error.MastraError({
2287
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_WORKFLOW_RUNS", "FAILED"),
2288
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2289
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
2290
+ text: `Failed to retrieve workflow runs: ${error instanceof Error ? error.message : String(error)}`,
2291
+ details: {
2292
+ workflowName: workflowName ?? "",
2293
+ resourceId: resourceId ?? ""
2294
+ }
2295
+ }, error);
2296
+ }
2297
+ }
2298
+ async getWorkflowRunById({ runId, workflowName }) {
2299
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
2300
+ try {
2301
+ const conditions = [];
2302
+ const params = [];
2303
+ if (runId) {
2304
+ conditions.push("run_id = ?");
2305
+ params.push(runId);
2306
+ }
2307
+ if (workflowName) {
2308
+ conditions.push("workflow_name = ?");
2309
+ params.push(workflowName);
2310
+ }
2311
+ const sql = `SELECT * FROM ${fullTableName} ${conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : ""} ORDER BY createdAt DESC LIMIT 1`;
2312
+ const result = await this.#db.executeQuery({
2313
+ sql,
2314
+ params,
2315
+ first: true
2316
+ });
2317
+ if (!result) return null;
2318
+ return this.parseWorkflowRun(result);
2319
+ } catch (error) {
2320
+ throw new _mastra_core_error.MastraError({
2321
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
2322
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2323
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
2324
+ text: `Failed to retrieve workflow run by ID: ${error instanceof Error ? error.message : String(error)}`,
2325
+ details: {
2326
+ runId,
2327
+ workflowName: workflowName ?? ""
2328
+ }
2329
+ }, error);
2330
+ }
2331
+ }
2332
+ async deleteWorkflowRunById({ runId, workflowName }) {
2333
+ const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
2334
+ try {
2335
+ const sql = `DELETE FROM ${fullTableName} WHERE workflow_name = ? AND run_id = ?`;
2336
+ const params = [workflowName, runId];
2337
+ await this.#db.executeQuery({
2338
+ sql,
2339
+ params
2340
+ });
2341
+ } catch (error) {
2342
+ throw new _mastra_core_error.MastraError({
2343
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
2344
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2345
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
2346
+ text: `Failed to delete workflow run by ID: ${error instanceof Error ? error.message : String(error)}`,
2347
+ details: {
2348
+ runId,
2349
+ workflowName
2350
+ }
2351
+ }, error);
2352
+ }
2353
+ }
2466
2354
  };
2467
-
2468
- // src/storage/index.ts
2469
- var D1Store = class extends storage.MastraCompositeStore {
2470
- client;
2471
- binding;
2472
- tablePrefix;
2473
- stores;
2474
- /**
2475
- * Creates a new D1Store instance
2476
- * @param config Configuration for D1 access (either REST API or Workers Binding API)
2477
- */
2478
- constructor(config) {
2479
- try {
2480
- super({ id: config.id, name: "D1", disableInit: config.disableInit });
2481
- if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) {
2482
- throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
2483
- }
2484
- this.tablePrefix = config.tablePrefix || "";
2485
- if ("binding" in config) {
2486
- if (!config.binding) {
2487
- throw new Error("D1 binding is required when using Workers Binding API");
2488
- }
2489
- this.binding = config.binding;
2490
- this.logger.info("Using D1 Workers Binding API");
2491
- } else if ("client" in config) {
2492
- if (!config.client) {
2493
- throw new Error("D1 client is required when using D1ClientConfig");
2494
- }
2495
- this.client = config.client;
2496
- this.logger.info("Using D1 Client");
2497
- } else {
2498
- if (!config.accountId || !config.databaseId || !config.apiToken) {
2499
- throw new Error("accountId, databaseId, and apiToken are required when using REST API");
2500
- }
2501
- const cfClient = new Cloudflare__default.default({
2502
- apiToken: config.apiToken
2503
- });
2504
- this.client = {
2505
- query: ({ sql, params }) => {
2506
- return cfClient.d1.database.query(config.databaseId, {
2507
- account_id: config.accountId,
2508
- sql,
2509
- params
2510
- });
2511
- }
2512
- };
2513
- this.logger.info("Using D1 REST API");
2514
- }
2515
- } catch (error$1) {
2516
- throw new error.MastraError(
2517
- {
2518
- id: storage.createStorageErrorId("CLOUDFLARE_D1", "INITIALIZATION", "FAILED"),
2519
- domain: error.ErrorDomain.STORAGE,
2520
- category: error.ErrorCategory.SYSTEM,
2521
- text: "Error initializing D1Store"
2522
- },
2523
- error$1
2524
- );
2525
- }
2526
- let scores;
2527
- let workflows;
2528
- let memory;
2529
- let backgroundTasks;
2530
- if (this.binding) {
2531
- const domainConfig = { binding: this.binding, tablePrefix: this.tablePrefix };
2532
- scores = new ScoresStorageD1(domainConfig);
2533
- workflows = new WorkflowsStorageD1(domainConfig);
2534
- memory = new MemoryStorageD1(domainConfig);
2535
- backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
2536
- } else {
2537
- const domainConfig = { client: this.client, tablePrefix: this.tablePrefix };
2538
- scores = new ScoresStorageD1(domainConfig);
2539
- workflows = new WorkflowsStorageD1(domainConfig);
2540
- memory = new MemoryStorageD1(domainConfig);
2541
- backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
2542
- }
2543
- this.stores = {
2544
- scores,
2545
- workflows,
2546
- memory,
2547
- backgroundTasks
2548
- };
2549
- }
2550
- /**
2551
- * Close the database connection
2552
- * No explicit cleanup needed for D1 in either REST or Workers Binding mode
2553
- */
2554
- async close() {
2555
- this.logger.debug("Closing D1 connection");
2556
- }
2355
+ //#endregion
2356
+ //#region src/storage/index.ts
2357
+ /**
2358
+ * Cloudflare D1 storage adapter for Mastra.
2359
+ *
2360
+ * Access domain-specific storage via `getStore()`:
2361
+ *
2362
+ * @example
2363
+ * ```typescript
2364
+ * const storage = new D1Store({ id: 'my-store', accountId: '...', apiToken: '...', databaseId: '...' });
2365
+ *
2366
+ * // Access memory domain
2367
+ * const memory = await storage.getStore('memory');
2368
+ * await memory?.saveThread({ thread });
2369
+ *
2370
+ * // Access workflows domain
2371
+ * const workflows = await storage.getStore('workflows');
2372
+ * await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2373
+ * ```
2374
+ */
2375
+ var D1Store = class extends _mastra_core_storage.MastraCompositeStore {
2376
+ client;
2377
+ binding;
2378
+ tablePrefix;
2379
+ stores;
2380
+ /**
2381
+ * Creates a new D1Store instance
2382
+ * @param config Configuration for D1 access (either REST API or Workers Binding API)
2383
+ */
2384
+ constructor(config) {
2385
+ try {
2386
+ super({
2387
+ id: config.id,
2388
+ name: "D1",
2389
+ disableInit: config.disableInit
2390
+ });
2391
+ if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
2392
+ this.tablePrefix = config.tablePrefix || "";
2393
+ if ("binding" in config) {
2394
+ if (!config.binding) throw new Error("D1 binding is required when using Workers Binding API");
2395
+ this.binding = config.binding;
2396
+ this.logger.info("Using D1 Workers Binding API");
2397
+ } else if ("client" in config) {
2398
+ if (!config.client) throw new Error("D1 client is required when using D1ClientConfig");
2399
+ this.client = config.client;
2400
+ this.logger.info("Using D1 Client");
2401
+ } else {
2402
+ if (!config.accountId || !config.databaseId || !config.apiToken) throw new Error("accountId, databaseId, and apiToken are required when using REST API");
2403
+ const cfClient = new cloudflare.default({ apiToken: config.apiToken });
2404
+ this.client = { query: ({ sql, params }) => {
2405
+ return cfClient.d1.database.query(config.databaseId, {
2406
+ account_id: config.accountId,
2407
+ sql,
2408
+ params
2409
+ });
2410
+ } };
2411
+ this.logger.info("Using D1 REST API");
2412
+ }
2413
+ } catch (error) {
2414
+ throw new _mastra_core_error.MastraError({
2415
+ id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "INITIALIZATION", "FAILED"),
2416
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
2417
+ category: _mastra_core_error.ErrorCategory.SYSTEM,
2418
+ text: "Error initializing D1Store"
2419
+ }, error);
2420
+ }
2421
+ let scores;
2422
+ let workflows;
2423
+ let memory;
2424
+ let backgroundTasks;
2425
+ if (this.binding) {
2426
+ const domainConfig = {
2427
+ binding: this.binding,
2428
+ tablePrefix: this.tablePrefix
2429
+ };
2430
+ scores = new ScoresStorageD1(domainConfig);
2431
+ workflows = new WorkflowsStorageD1(domainConfig);
2432
+ memory = new MemoryStorageD1(domainConfig);
2433
+ backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
2434
+ } else {
2435
+ const domainConfig = {
2436
+ client: this.client,
2437
+ tablePrefix: this.tablePrefix
2438
+ };
2439
+ scores = new ScoresStorageD1(domainConfig);
2440
+ workflows = new WorkflowsStorageD1(domainConfig);
2441
+ memory = new MemoryStorageD1(domainConfig);
2442
+ backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
2443
+ }
2444
+ this.stores = {
2445
+ scores,
2446
+ workflows,
2447
+ memory,
2448
+ backgroundTasks
2449
+ };
2450
+ }
2451
+ /**
2452
+ * Close the database connection
2453
+ * No explicit cleanup needed for D1 in either REST or Workers Binding mode
2454
+ */
2455
+ async close() {
2456
+ this.logger.debug("Closing D1 connection");
2457
+ }
2557
2458
  };
2558
-
2459
+ //#endregion
2559
2460
  exports.BackgroundTasksStorageD1 = BackgroundTasksStorageD1;
2560
2461
  exports.D1Store = D1Store;
2561
2462
  exports.MemoryStorageD1 = MemoryStorageD1;
2562
2463
  exports.ScoresStorageD1 = ScoresStorageD1;
2563
2464
  exports.WorkflowsStorageD1 = WorkflowsStorageD1;
2564
- //# sourceMappingURL=index.cjs.map
2465
+
2565
2466
  //# sourceMappingURL=index.cjs.map