@mastra/cloudflare-d1 0.12.0 → 0.12.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,6 +54,21 @@ const store = new D1Store({
54
54
  });
55
55
  ```
56
56
 
57
+ ### Or you can pass any client implementation you want
58
+
59
+ ```typescript
60
+ import { D1Store } from '@mastra/cloudflare-d1';
61
+
62
+ const store = new D1Store({
63
+ client: {
64
+ query: ({ sql, params }) => {
65
+ // do something
66
+ },
67
+ },
68
+ tablePrefix: 'mastra_', // optional
69
+ });
70
+ ```
71
+
57
72
  ## Supported Methods
58
73
 
59
74
  ### Thread Operations
@@ -1,3 +1,4 @@
1
+ import { default as Cloudflare_2 } from 'cloudflare';
1
2
  import type { D1Database as D1Database_2 } from '@cloudflare/workers-types';
2
3
  import type { EvalRow } from '@mastra/core/storage';
3
4
  import type { MastraMessageContentV2 } from '@mastra/core/agent';
@@ -33,6 +34,26 @@ export declare const createSampleTrace: (name: string, scope?: string, attribute
33
34
 
34
35
  export declare function createSqlBuilder(): SqlBuilder;
35
36
 
37
+ declare interface D1Client {
38
+ query(args: {
39
+ sql: string;
40
+ params: string[];
41
+ }): Promise<{
42
+ result: D1QueryResult;
43
+ }>;
44
+ }
45
+ export { D1Client }
46
+ export { D1Client as D1Client_alias_1 }
47
+
48
+ declare interface D1ClientConfig {
49
+ /** Optional prefix for table names */
50
+ tablePrefix?: string;
51
+ /** D1 Client */
52
+ client: D1Client;
53
+ }
54
+ export { D1ClientConfig }
55
+ export { D1ClientConfig as D1ClientConfig_alias_1 }
56
+
36
57
  /**
37
58
  * Configuration for D1 using the REST API
38
59
  */
@@ -49,10 +70,12 @@ declare interface D1Config {
49
70
  export { D1Config }
50
71
  export { D1Config as D1Config_alias_1 }
51
72
 
73
+ declare type D1QueryResult = Awaited<ReturnType<Cloudflare_2['d1']['database']['query']>>['result'];
74
+ export { D1QueryResult }
75
+ export { D1QueryResult as D1QueryResult_alias_1 }
76
+
52
77
  declare class D1Store extends MastraStorage {
53
78
  private client?;
54
- private accountId?;
55
- private databaseId?;
56
79
  private binding?;
57
80
  private tablePrefix;
58
81
  /**
@@ -247,7 +270,7 @@ export { D1Store as D1Store_alias_1 }
247
270
  /**
248
271
  * Combined configuration type supporting both REST API and Workers Binding API
249
272
  */
250
- declare type D1StoreConfig = D1Config | D1WorkersConfig;
273
+ declare type D1StoreConfig = D1Config | D1WorkersConfig | D1ClientConfig;
251
274
  export { D1StoreConfig }
252
275
  export { D1StoreConfig as D1StoreConfig_alias_1 }
253
276
 
@@ -1,3 +1,4 @@
1
+ import { default as Cloudflare_2 } from 'cloudflare';
1
2
  import type { D1Database as D1Database_2 } from '@cloudflare/workers-types';
2
3
  import type { EvalRow } from '@mastra/core/storage';
3
4
  import type { MastraMessageContentV2 } from '@mastra/core/agent';
@@ -33,6 +34,26 @@ export declare const createSampleTrace: (name: string, scope?: string, attribute
33
34
 
34
35
  export declare function createSqlBuilder(): SqlBuilder;
35
36
 
37
+ declare interface D1Client {
38
+ query(args: {
39
+ sql: string;
40
+ params: string[];
41
+ }): Promise<{
42
+ result: D1QueryResult;
43
+ }>;
44
+ }
45
+ export { D1Client }
46
+ export { D1Client as D1Client_alias_1 }
47
+
48
+ declare interface D1ClientConfig {
49
+ /** Optional prefix for table names */
50
+ tablePrefix?: string;
51
+ /** D1 Client */
52
+ client: D1Client;
53
+ }
54
+ export { D1ClientConfig }
55
+ export { D1ClientConfig as D1ClientConfig_alias_1 }
56
+
36
57
  /**
37
58
  * Configuration for D1 using the REST API
38
59
  */
@@ -49,10 +70,12 @@ declare interface D1Config {
49
70
  export { D1Config }
50
71
  export { D1Config as D1Config_alias_1 }
51
72
 
73
+ declare type D1QueryResult = Awaited<ReturnType<Cloudflare_2['d1']['database']['query']>>['result'];
74
+ export { D1QueryResult }
75
+ export { D1QueryResult as D1QueryResult_alias_1 }
76
+
52
77
  declare class D1Store extends MastraStorage {
53
78
  private client?;
54
- private accountId?;
55
- private databaseId?;
56
79
  private binding?;
57
80
  private tablePrefix;
58
81
  /**
@@ -247,7 +270,7 @@ export { D1Store as D1Store_alias_1 }
247
270
  /**
248
271
  * Combined configuration type supporting both REST API and Workers Binding API
249
272
  */
250
- declare type D1StoreConfig = D1Config | D1WorkersConfig;
273
+ declare type D1StoreConfig = D1Config | D1WorkersConfig | D1ClientConfig;
251
274
  export { D1StoreConfig }
252
275
  export { D1StoreConfig as D1StoreConfig_alias_1 }
253
276
 
package/dist/index.cjs CHANGED
@@ -247,8 +247,6 @@ function isArrayOfRecords(value) {
247
247
  }
248
248
  var D1Store = class extends storage.MastraStorage {
249
249
  client;
250
- accountId;
251
- databaseId;
252
250
  binding;
253
251
  // D1Database binding
254
252
  tablePrefix;
@@ -269,15 +267,28 @@ var D1Store = class extends storage.MastraStorage {
269
267
  }
270
268
  this.binding = config.binding;
271
269
  this.logger.info("Using D1 Workers Binding API");
270
+ } else if ("client" in config) {
271
+ if (!config.client) {
272
+ throw new Error("D1 client is required when using D1ClientConfig");
273
+ }
274
+ this.client = config.client;
275
+ this.logger.info("Using D1 Client");
272
276
  } else {
273
277
  if (!config.accountId || !config.databaseId || !config.apiToken) {
274
278
  throw new Error("accountId, databaseId, and apiToken are required when using REST API");
275
279
  }
276
- this.accountId = config.accountId;
277
- this.databaseId = config.databaseId;
278
- this.client = new Cloudflare__default.default({
280
+ const cfClient = new Cloudflare__default.default({
279
281
  apiToken: config.apiToken
280
282
  });
283
+ this.client = {
284
+ query: ({ sql, params }) => {
285
+ return cfClient.d1.database.query(config.databaseId, {
286
+ account_id: config.accountId,
287
+ sql,
288
+ params
289
+ });
290
+ }
291
+ };
281
292
  this.logger.info("Using D1 REST API");
282
293
  }
283
294
  } catch (error$1) {
@@ -351,12 +362,11 @@ var D1Store = class extends storage.MastraStorage {
351
362
  params = [],
352
363
  first = false
353
364
  }) {
354
- if (!this.client || !this.accountId || !this.databaseId) {
365
+ if (!this.client) {
355
366
  throw new Error("Missing required REST API configuration");
356
367
  }
357
368
  try {
358
- const response = await this.client.d1.database.query(this.databaseId, {
359
- account_id: this.accountId,
369
+ const response = await this.client.query({
360
370
  sql,
361
371
  params: this.formatSqlParams(params)
362
372
  });
@@ -387,7 +397,7 @@ var D1Store = class extends storage.MastraStorage {
387
397
  this.logger.debug("Executing SQL query", { sql, params, first });
388
398
  if (this.binding) {
389
399
  return this.executeWorkersBindingQuery({ sql, params, first });
390
- } else if (this.client && this.accountId && this.databaseId) {
400
+ } else if (this.client) {
391
401
  return this.executeRestQuery({ sql, params, first });
392
402
  } else {
393
403
  throw new Error("No valid D1 configuration provided");
@@ -841,9 +851,15 @@ var D1Store = class extends storage.MastraStorage {
841
851
  const threadId = messages[0]?.threadId;
842
852
  for (const [i, message] of messages.entries()) {
843
853
  if (!message.id) throw new Error(`Message at index ${i} missing id`);
844
- if (!message.threadId) throw new Error(`Message at index ${i} missing threadId`);
845
- if (!message.content) throw new Error(`Message at index ${i} missing content`);
846
- if (!message.role) throw new Error(`Message at index ${i} missing role`);
854
+ if (!message.threadId) {
855
+ throw new Error(`Message at index ${i} missing threadId`);
856
+ }
857
+ if (!message.content) {
858
+ throw new Error(`Message at index ${i} missing content`);
859
+ }
860
+ if (!message.role) {
861
+ throw new Error(`Message at index ${i} missing role`);
862
+ }
847
863
  const thread = await this.getThreadById({ threadId: message.threadId });
848
864
  if (!thread) {
849
865
  throw new Error(`Thread ${message.threadId} not found`);
@@ -940,7 +956,10 @@ var D1Store = class extends storage.MastraStorage {
940
956
  format
941
957
  }) {
942
958
  const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
943
- const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
959
+ const limit = this.resolveMessageLimit({
960
+ last: selectBy?.last,
961
+ defaultLimit: 40
962
+ });
944
963
  const include = selectBy?.include || [];
945
964
  const messages = [];
946
965
  try {
@@ -1433,7 +1452,11 @@ var D1Store = class extends storage.MastraStorage {
1433
1452
  }
1434
1453
  const { sql: countSql, params: countParams } = countQueryBuilder.build();
1435
1454
  try {
1436
- const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
1455
+ const countResult = await this.executeQuery({
1456
+ sql: countSql,
1457
+ params: countParams,
1458
+ first: true
1459
+ });
1437
1460
  const total = Number(countResult?.count || 0);
1438
1461
  const currentOffset = page * perPage;
1439
1462
  if (total === 0) {
@@ -1451,7 +1474,10 @@ var D1Store = class extends storage.MastraStorage {
1451
1474
  }
1452
1475
  dataQueryBuilder.orderBy("createdAt", "DESC").limit(perPage).offset(currentOffset);
1453
1476
  const { sql: dataSql, params: dataParams } = dataQueryBuilder.build();
1454
- const rows = await this.executeQuery({ sql: dataSql, params: dataParams });
1477
+ const rows = await this.executeQuery({
1478
+ sql: dataSql,
1479
+ params: dataParams
1480
+ });
1455
1481
  const evals = (isArrayOfRecords(rows) ? rows : []).map((row) => {
1456
1482
  const result = this.deserializeValue(row.result);
1457
1483
  const testInfo = row.test_info ? this.deserializeValue(row.test_info) : void 0;
@@ -1553,7 +1579,11 @@ var D1Store = class extends storage.MastraStorage {
1553
1579
  let total = 0;
1554
1580
  if (limit !== void 0 && offset !== void 0) {
1555
1581
  const { sql: countSql, params: countParams } = countBuilder.build();
1556
- const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
1582
+ const countResult = await this.executeQuery({
1583
+ sql: countSql,
1584
+ params: countParams,
1585
+ first: true
1586
+ });
1557
1587
  total = Number(countResult?.count ?? 0);
1558
1588
  }
1559
1589
  const results = await this.executeQuery({ sql, params });
@@ -1566,7 +1596,10 @@ var D1Store = class extends storage.MastraStorage {
1566
1596
  domain: error.ErrorDomain.STORAGE,
1567
1597
  category: error.ErrorCategory.THIRD_PARTY,
1568
1598
  text: `Failed to retrieve workflow runs: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1569
- details: { workflowName: workflowName ?? "", resourceId: resourceId ?? "" }
1599
+ details: {
1600
+ workflowName: workflowName ?? "",
1601
+ resourceId: resourceId ?? ""
1602
+ }
1570
1603
  },
1571
1604
  error$1
1572
1605
  );
package/dist/index.d.cts CHANGED
@@ -1,4 +1,7 @@
1
1
  export { D1Config } from './_tsup-dts-rollup.cjs';
2
+ export { D1ClientConfig } from './_tsup-dts-rollup.cjs';
2
3
  export { D1WorkersConfig } from './_tsup-dts-rollup.cjs';
3
4
  export { D1StoreConfig } from './_tsup-dts-rollup.cjs';
5
+ export { D1QueryResult } from './_tsup-dts-rollup.cjs';
6
+ export { D1Client } from './_tsup-dts-rollup.cjs';
4
7
  export { D1Store } from './_tsup-dts-rollup.cjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export { D1Config } from './_tsup-dts-rollup.js';
2
+ export { D1ClientConfig } from './_tsup-dts-rollup.js';
2
3
  export { D1WorkersConfig } from './_tsup-dts-rollup.js';
3
4
  export { D1StoreConfig } from './_tsup-dts-rollup.js';
5
+ export { D1QueryResult } from './_tsup-dts-rollup.js';
6
+ export { D1Client } from './_tsup-dts-rollup.js';
4
7
  export { D1Store } from './_tsup-dts-rollup.js';
package/dist/index.js CHANGED
@@ -241,8 +241,6 @@ function isArrayOfRecords(value) {
241
241
  }
242
242
  var D1Store = class extends MastraStorage {
243
243
  client;
244
- accountId;
245
- databaseId;
246
244
  binding;
247
245
  // D1Database binding
248
246
  tablePrefix;
@@ -263,15 +261,28 @@ var D1Store = class extends MastraStorage {
263
261
  }
264
262
  this.binding = config.binding;
265
263
  this.logger.info("Using D1 Workers Binding API");
264
+ } else if ("client" in config) {
265
+ if (!config.client) {
266
+ throw new Error("D1 client is required when using D1ClientConfig");
267
+ }
268
+ this.client = config.client;
269
+ this.logger.info("Using D1 Client");
266
270
  } else {
267
271
  if (!config.accountId || !config.databaseId || !config.apiToken) {
268
272
  throw new Error("accountId, databaseId, and apiToken are required when using REST API");
269
273
  }
270
- this.accountId = config.accountId;
271
- this.databaseId = config.databaseId;
272
- this.client = new Cloudflare({
274
+ const cfClient = new Cloudflare({
273
275
  apiToken: config.apiToken
274
276
  });
277
+ this.client = {
278
+ query: ({ sql, params }) => {
279
+ return cfClient.d1.database.query(config.databaseId, {
280
+ account_id: config.accountId,
281
+ sql,
282
+ params
283
+ });
284
+ }
285
+ };
275
286
  this.logger.info("Using D1 REST API");
276
287
  }
277
288
  } catch (error) {
@@ -345,12 +356,11 @@ var D1Store = class extends MastraStorage {
345
356
  params = [],
346
357
  first = false
347
358
  }) {
348
- if (!this.client || !this.accountId || !this.databaseId) {
359
+ if (!this.client) {
349
360
  throw new Error("Missing required REST API configuration");
350
361
  }
351
362
  try {
352
- const response = await this.client.d1.database.query(this.databaseId, {
353
- account_id: this.accountId,
363
+ const response = await this.client.query({
354
364
  sql,
355
365
  params: this.formatSqlParams(params)
356
366
  });
@@ -381,7 +391,7 @@ var D1Store = class extends MastraStorage {
381
391
  this.logger.debug("Executing SQL query", { sql, params, first });
382
392
  if (this.binding) {
383
393
  return this.executeWorkersBindingQuery({ sql, params, first });
384
- } else if (this.client && this.accountId && this.databaseId) {
394
+ } else if (this.client) {
385
395
  return this.executeRestQuery({ sql, params, first });
386
396
  } else {
387
397
  throw new Error("No valid D1 configuration provided");
@@ -835,9 +845,15 @@ var D1Store = class extends MastraStorage {
835
845
  const threadId = messages[0]?.threadId;
836
846
  for (const [i, message] of messages.entries()) {
837
847
  if (!message.id) throw new Error(`Message at index ${i} missing id`);
838
- if (!message.threadId) throw new Error(`Message at index ${i} missing threadId`);
839
- if (!message.content) throw new Error(`Message at index ${i} missing content`);
840
- if (!message.role) throw new Error(`Message at index ${i} missing role`);
848
+ if (!message.threadId) {
849
+ throw new Error(`Message at index ${i} missing threadId`);
850
+ }
851
+ if (!message.content) {
852
+ throw new Error(`Message at index ${i} missing content`);
853
+ }
854
+ if (!message.role) {
855
+ throw new Error(`Message at index ${i} missing role`);
856
+ }
841
857
  const thread = await this.getThreadById({ threadId: message.threadId });
842
858
  if (!thread) {
843
859
  throw new Error(`Thread ${message.threadId} not found`);
@@ -934,7 +950,10 @@ var D1Store = class extends MastraStorage {
934
950
  format
935
951
  }) {
936
952
  const fullTableName = this.getTableName(TABLE_MESSAGES);
937
- const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
953
+ const limit = this.resolveMessageLimit({
954
+ last: selectBy?.last,
955
+ defaultLimit: 40
956
+ });
938
957
  const include = selectBy?.include || [];
939
958
  const messages = [];
940
959
  try {
@@ -1427,7 +1446,11 @@ var D1Store = class extends MastraStorage {
1427
1446
  }
1428
1447
  const { sql: countSql, params: countParams } = countQueryBuilder.build();
1429
1448
  try {
1430
- const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
1449
+ const countResult = await this.executeQuery({
1450
+ sql: countSql,
1451
+ params: countParams,
1452
+ first: true
1453
+ });
1431
1454
  const total = Number(countResult?.count || 0);
1432
1455
  const currentOffset = page * perPage;
1433
1456
  if (total === 0) {
@@ -1445,7 +1468,10 @@ var D1Store = class extends MastraStorage {
1445
1468
  }
1446
1469
  dataQueryBuilder.orderBy("createdAt", "DESC").limit(perPage).offset(currentOffset);
1447
1470
  const { sql: dataSql, params: dataParams } = dataQueryBuilder.build();
1448
- const rows = await this.executeQuery({ sql: dataSql, params: dataParams });
1471
+ const rows = await this.executeQuery({
1472
+ sql: dataSql,
1473
+ params: dataParams
1474
+ });
1449
1475
  const evals = (isArrayOfRecords(rows) ? rows : []).map((row) => {
1450
1476
  const result = this.deserializeValue(row.result);
1451
1477
  const testInfo = row.test_info ? this.deserializeValue(row.test_info) : void 0;
@@ -1547,7 +1573,11 @@ var D1Store = class extends MastraStorage {
1547
1573
  let total = 0;
1548
1574
  if (limit !== void 0 && offset !== void 0) {
1549
1575
  const { sql: countSql, params: countParams } = countBuilder.build();
1550
- const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
1576
+ const countResult = await this.executeQuery({
1577
+ sql: countSql,
1578
+ params: countParams,
1579
+ first: true
1580
+ });
1551
1581
  total = Number(countResult?.count ?? 0);
1552
1582
  }
1553
1583
  const results = await this.executeQuery({ sql, params });
@@ -1560,7 +1590,10 @@ var D1Store = class extends MastraStorage {
1560
1590
  domain: ErrorDomain.STORAGE,
1561
1591
  category: ErrorCategory.THIRD_PARTY,
1562
1592
  text: `Failed to retrieve workflow runs: ${error instanceof Error ? error.message : String(error)}`,
1563
- details: { workflowName: workflowName ?? "", resourceId: resourceId ?? "" }
1593
+ details: {
1594
+ workflowName: workflowName ?? "",
1595
+ resourceId: resourceId ?? ""
1596
+ }
1564
1597
  },
1565
1598
  error
1566
1599
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/cloudflare-d1",
3
- "version": "0.12.0",
3
+ "version": "0.12.1-alpha.0",
4
4
  "description": "D1 provider for Mastra - includes db storage capabilities",
5
5
  "type": "module",
6
6
  "files": [
@@ -25,18 +25,18 @@
25
25
  "cloudflare": "^4.4.1"
26
26
  },
27
27
  "devDependencies": {
28
- "@cloudflare/workers-types": "^4.20250620.0",
28
+ "@cloudflare/workers-types": "^4.20250705.0",
29
29
  "@microsoft/api-extractor": "^7.52.8",
30
30
  "@types/node": "^20.19.0",
31
- "dotenv": "^16.5.0",
31
+ "dotenv": "^17.0.0",
32
32
  "eslint": "^9.29.0",
33
- "miniflare": "^4.20250617.3",
33
+ "miniflare": "^4.20250617.5",
34
34
  "tsup": "^8.5.0",
35
35
  "typescript": "^5.8.3",
36
- "vitest": "^3.2.3",
37
- "@internal/storage-test-utils": "0.0.10",
38
- "@internal/lint": "0.0.14",
39
- "@mastra/core": "0.10.7"
36
+ "vitest": "^3.2.4",
37
+ "@internal/lint": "0.0.17",
38
+ "@mastra/core": "0.10.11-alpha.2",
39
+ "@internal/storage-test-utils": "0.0.13"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@mastra/core": ">=0.10.7-0 <0.11.0-0"