@mastra/dynamodb 1.0.0-beta.10 → 1.0.0-beta.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # @mastra/dynamodb
2
2
 
3
+ ## 1.0.0-beta.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Renamed MastraStorage to MastraCompositeStore for better clarity. The old MastraStorage name remains available as a deprecated alias for backward compatibility, but will be removed in a future version. ([#12093](https://github.com/mastra-ai/mastra/pull/12093))
8
+
9
+ **Migration:**
10
+
11
+ Update your imports and usage:
12
+
13
+ ```typescript
14
+ // Before
15
+ import { MastraStorage } from '@mastra/core/storage';
16
+
17
+ const storage = new MastraStorage({
18
+ id: 'composite',
19
+ domains: { ... }
20
+ });
21
+
22
+ // After
23
+ import { MastraCompositeStore } from '@mastra/core/storage';
24
+
25
+ const storage = new MastraCompositeStore({
26
+ id: 'composite',
27
+ domains: { ... }
28
+ });
29
+ ```
30
+
31
+ The new name better reflects that this is a composite storage implementation that routes different domains (workflows, traces, messages) to different underlying stores, avoiding confusion with the general "Mastra Storage" concept.
32
+
33
+ - Updated dependencies [[`026b848`](https://github.com/mastra-ai/mastra/commit/026b8483fbf5b6d977be8f7e6aac8d15c75558ac), [`ffa553a`](https://github.com/mastra-ai/mastra/commit/ffa553a3edc1bd17d73669fba66d6b6f4ac10897)]:
34
+ - @mastra/core@1.0.0-beta.26
35
+
36
+ ## 1.0.0-beta.11
37
+
38
+ ### Patch Changes
39
+
40
+ - Added new `listThreads` method for flexible thread filtering across all storage adapters. ([#11832](https://github.com/mastra-ai/mastra/pull/11832))
41
+
42
+ **New Features**
43
+ - Filter threads by `resourceId`, `metadata`, or both (with AND logic for metadata key-value pairs)
44
+ - All filter parameters are optional, allowing you to list all threads or filter as needed
45
+ - Full pagination and sorting support
46
+
47
+ **Example Usage**
48
+
49
+ ```typescript
50
+ // List all threads
51
+ const allThreads = await memory.listThreads({});
52
+
53
+ // Filter by resourceId only
54
+ const userThreads = await memory.listThreads({
55
+ filter: { resourceId: 'user-123' },
56
+ });
57
+
58
+ // Filter by metadata only
59
+ const supportThreads = await memory.listThreads({
60
+ filter: { metadata: { category: 'support' } },
61
+ });
62
+
63
+ // Filter by both with pagination
64
+ const filteredThreads = await memory.listThreads({
65
+ filter: {
66
+ resourceId: 'user-123',
67
+ metadata: { priority: 'high', status: 'open' },
68
+ },
69
+ orderBy: { field: 'updatedAt', direction: 'DESC' },
70
+ page: 0,
71
+ perPage: 20,
72
+ });
73
+ ```
74
+
75
+ **Security Improvements**
76
+ - Added validation to prevent SQL injection via malicious metadata keys
77
+ - Added pagination parameter validation to prevent integer overflow attacks
78
+
79
+ - Updated dependencies [[`ed3e3dd`](https://github.com/mastra-ai/mastra/commit/ed3e3ddec69d564fe2b125e083437f76331f1283), [`6833c69`](https://github.com/mastra-ai/mastra/commit/6833c69607418d257750bbcdd84638993d343539), [`47b1c16`](https://github.com/mastra-ai/mastra/commit/47b1c16a01c7ffb6765fe1e499b49092f8b7eba3), [`3a76a80`](https://github.com/mastra-ai/mastra/commit/3a76a80284cb71a0faa975abb3d4b2a9631e60cd), [`8538a0d`](https://github.com/mastra-ai/mastra/commit/8538a0d232619bf55dad7ddc2a8b0ca77c679a87), [`9312dcd`](https://github.com/mastra-ai/mastra/commit/9312dcd1c6f5b321929e7d382e763d95fdc030f5)]:
80
+ - @mastra/core@1.0.0-beta.25
81
+
3
82
  ## 1.0.0-beta.10
4
83
 
5
84
  ### Minor Changes
@@ -28,4 +28,4 @@ docs/
28
28
  ## Version
29
29
 
30
30
  Package: @mastra/dynamodb
31
- Version: 1.0.0-beta.10
31
+ Version: 1.0.0-beta.12
@@ -5,7 +5,7 @@ description: Documentation for @mastra/dynamodb. Includes links to type definiti
5
5
 
6
6
  # @mastra/dynamodb Documentation
7
7
 
8
- > **Version**: 1.0.0-beta.10
8
+ > **Version**: 1.0.0-beta.12
9
9
  > **Package**: @mastra/dynamodb
10
10
 
11
11
  ## Quick Navigation
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-beta.10",
2
+ "version": "1.0.0-beta.12",
3
3
  "package": "@mastra/dynamodb",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -1506,33 +1506,57 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1506
1506
  );
1507
1507
  }
1508
1508
  }
1509
- async listThreadsByResourceId(args) {
1510
- const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
1511
- const perPage = storage.normalizePerPage(perPageInput, 100);
1512
- if (page < 0) {
1509
+ async listThreads(args) {
1510
+ const { page = 0, perPage: perPageInput, orderBy, filter } = args;
1511
+ try {
1512
+ this.validatePaginationInput(page, perPageInput ?? 100);
1513
+ } catch (error$1) {
1513
1514
  throw new error.MastraError(
1514
1515
  {
1515
- id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
1516
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS", "INVALID_PAGE"),
1516
1517
  domain: error.ErrorDomain.STORAGE,
1517
1518
  category: error.ErrorCategory.USER,
1518
- details: { page }
1519
+ details: {
1520
+ page,
1521
+ ...perPageInput !== void 0 && { perPage: perPageInput }
1522
+ }
1519
1523
  },
1520
- new Error("page must be >= 0")
1524
+ error$1 instanceof Error ? error$1 : new Error("Invalid pagination parameters")
1521
1525
  );
1522
1526
  }
1527
+ const perPage = storage.normalizePerPage(perPageInput, 100);
1523
1528
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1524
1529
  const { field, direction } = this.parseOrderBy(orderBy);
1525
- this.logger.debug("Getting threads by resource ID with pagination", {
1526
- resourceId,
1530
+ this.logger.debug("Listing threads with filters", {
1531
+ resourceId: filter?.resourceId,
1532
+ metadataKeys: filter?.metadata ? Object.keys(filter.metadata) : [],
1527
1533
  page,
1528
1534
  perPage,
1529
1535
  field,
1530
1536
  direction
1531
1537
  });
1532
1538
  try {
1533
- const query = this.service.entities.thread.query.byResource({ entity: "thread", resourceId });
1534
- const results = await query.go();
1535
- const allThreads = this.transformAndSortThreads(results.data, field, direction);
1539
+ const rawThreads = filter?.resourceId ? (await this.service.entities.thread.query.byResource({
1540
+ entity: "thread",
1541
+ resourceId: filter.resourceId
1542
+ }).go({ pages: "all" })).data : (await this.service.entities.thread.scan.go({ pages: "all" })).data;
1543
+ let allThreads = this.transformAndSortThreads(rawThreads, field, direction);
1544
+ if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
1545
+ allThreads = allThreads.filter((thread) => {
1546
+ let threadMeta = null;
1547
+ if (typeof thread.metadata === "string") {
1548
+ try {
1549
+ threadMeta = JSON.parse(thread.metadata);
1550
+ } catch {
1551
+ return false;
1552
+ }
1553
+ } else if (thread.metadata && typeof thread.metadata === "object") {
1554
+ threadMeta = thread.metadata;
1555
+ }
1556
+ if (!threadMeta) return false;
1557
+ return Object.entries(filter.metadata).every(([key, value]) => threadMeta[key] === value);
1558
+ });
1559
+ }
1536
1560
  const endIndex = offset + perPage;
1537
1561
  const paginatedThreads = allThreads.slice(offset, endIndex);
1538
1562
  const total = allThreads.length;
@@ -1547,10 +1571,15 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1547
1571
  } catch (error$1) {
1548
1572
  throw new error.MastraError(
1549
1573
  {
1550
- id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
1574
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS", "FAILED"),
1551
1575
  domain: error.ErrorDomain.STORAGE,
1552
1576
  category: error.ErrorCategory.THIRD_PARTY,
1553
- details: { resourceId, page, perPage }
1577
+ details: {
1578
+ ...filter?.resourceId && { resourceId: filter.resourceId },
1579
+ hasMetadataFilter: !!(filter?.metadata && Object.keys(filter.metadata).length),
1580
+ page,
1581
+ perPage: perPageForResponse
1582
+ }
1554
1583
  },
1555
1584
  error$1
1556
1585
  );
@@ -2428,7 +2457,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2428
2457
  var isClientConfig = (config) => {
2429
2458
  return "client" in config;
2430
2459
  };
2431
- var DynamoDBStore = class extends storage.MastraStorage {
2460
+ var DynamoDBStore = class extends storage.MastraCompositeStore {
2432
2461
  tableName;
2433
2462
  client;
2434
2463
  service;