@mastra/cloudflare-d1 1.0.0-beta.10 → 1.0.0-beta.11
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 +46 -0
- package/dist/docs/README.md +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +72 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -11
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -2
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @mastra/cloudflare-d1
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Added new `listThreads` method for flexible thread filtering across all storage adapters. ([#11832](https://github.com/mastra-ai/mastra/pull/11832))
|
|
8
|
+
|
|
9
|
+
**New Features**
|
|
10
|
+
- Filter threads by `resourceId`, `metadata`, or both (with AND logic for metadata key-value pairs)
|
|
11
|
+
- All filter parameters are optional, allowing you to list all threads or filter as needed
|
|
12
|
+
- Full pagination and sorting support
|
|
13
|
+
|
|
14
|
+
**Example Usage**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// List all threads
|
|
18
|
+
const allThreads = await memory.listThreads({});
|
|
19
|
+
|
|
20
|
+
// Filter by resourceId only
|
|
21
|
+
const userThreads = await memory.listThreads({
|
|
22
|
+
filter: { resourceId: 'user-123' },
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Filter by metadata only
|
|
26
|
+
const supportThreads = await memory.listThreads({
|
|
27
|
+
filter: { metadata: { category: 'support' } },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Filter by both with pagination
|
|
31
|
+
const filteredThreads = await memory.listThreads({
|
|
32
|
+
filter: {
|
|
33
|
+
resourceId: 'user-123',
|
|
34
|
+
metadata: { priority: 'high', status: 'open' },
|
|
35
|
+
},
|
|
36
|
+
orderBy: { field: 'updatedAt', direction: 'DESC' },
|
|
37
|
+
page: 0,
|
|
38
|
+
perPage: 20,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Security Improvements**
|
|
43
|
+
- Added validation to prevent SQL injection via malicious metadata keys
|
|
44
|
+
- Added pagination parameter validation to prevent integer overflow attacks
|
|
45
|
+
|
|
46
|
+
- 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)]:
|
|
47
|
+
- @mastra/core@1.0.0-beta.25
|
|
48
|
+
|
|
3
49
|
## 1.0.0-beta.10
|
|
4
50
|
|
|
5
51
|
### Patch Changes
|
package/dist/docs/README.md
CHANGED
package/dist/docs/SKILL.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -846,18 +846,33 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
|
846
846
|
return null;
|
|
847
847
|
}
|
|
848
848
|
}
|
|
849
|
-
async
|
|
850
|
-
const {
|
|
849
|
+
async listThreads(args) {
|
|
850
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
851
|
+
try {
|
|
852
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
853
|
+
} catch (error$1) {
|
|
854
|
+
throw new error.MastraError(
|
|
855
|
+
{
|
|
856
|
+
id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_PAGE"),
|
|
857
|
+
domain: error.ErrorDomain.STORAGE,
|
|
858
|
+
category: error.ErrorCategory.USER,
|
|
859
|
+
details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
|
|
860
|
+
},
|
|
861
|
+
error$1 instanceof Error ? error$1 : new Error("Invalid pagination parameters")
|
|
862
|
+
);
|
|
863
|
+
}
|
|
851
864
|
const perPage = storage.normalizePerPage(perPageInput, 100);
|
|
852
|
-
|
|
865
|
+
try {
|
|
866
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
867
|
+
} catch (error$1) {
|
|
853
868
|
throw new error.MastraError(
|
|
854
869
|
{
|
|
855
|
-
id: storage.createStorageErrorId("CLOUDFLARE_D1", "
|
|
870
|
+
id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
856
871
|
domain: error.ErrorDomain.STORAGE,
|
|
857
872
|
category: error.ErrorCategory.USER,
|
|
858
|
-
details: {
|
|
873
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
859
874
|
},
|
|
860
|
-
new Error("
|
|
875
|
+
error$1 instanceof Error ? error$1 : new Error("Invalid metadata key")
|
|
861
876
|
);
|
|
862
877
|
}
|
|
863
878
|
const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
@@ -870,11 +885,51 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
|
870
885
|
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
|
|
871
886
|
});
|
|
872
887
|
try {
|
|
873
|
-
|
|
888
|
+
let countQuery = createSqlBuilder().count().from(fullTableName);
|
|
889
|
+
let selectQuery = createSqlBuilder().select("*").from(fullTableName);
|
|
890
|
+
if (filter?.resourceId) {
|
|
891
|
+
countQuery = countQuery.whereAnd("resourceId = ?", filter.resourceId);
|
|
892
|
+
selectQuery = selectQuery.whereAnd("resourceId = ?", filter.resourceId);
|
|
893
|
+
}
|
|
894
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
895
|
+
for (const [key, value] of Object.entries(filter.metadata)) {
|
|
896
|
+
if (value !== null && typeof value === "object") {
|
|
897
|
+
throw new error.MastraError(
|
|
898
|
+
{
|
|
899
|
+
id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_VALUE"),
|
|
900
|
+
domain: error.ErrorDomain.STORAGE,
|
|
901
|
+
category: error.ErrorCategory.USER,
|
|
902
|
+
text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${Array.isArray(value) ? "array" : "object"}`,
|
|
903
|
+
details: { key, valueType: Array.isArray(value) ? "array" : "object" }
|
|
904
|
+
},
|
|
905
|
+
new Error("Invalid metadata filter value type")
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
if (value === null) {
|
|
909
|
+
const condition = `json_extract(metadata, '$.${key}') IS NULL`;
|
|
910
|
+
countQuery = countQuery.whereAnd(condition);
|
|
911
|
+
selectQuery = selectQuery.whereAnd(condition);
|
|
912
|
+
} else {
|
|
913
|
+
const condition = `json_extract(metadata, '$.${key}') = ?`;
|
|
914
|
+
const filterValue = value;
|
|
915
|
+
countQuery = countQuery.whereAnd(condition, filterValue);
|
|
916
|
+
selectQuery = selectQuery.whereAnd(condition, filterValue);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
874
920
|
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
875
921
|
const total = Number(countResult?.[0]?.count ?? 0);
|
|
922
|
+
if (total === 0) {
|
|
923
|
+
return {
|
|
924
|
+
threads: [],
|
|
925
|
+
total: 0,
|
|
926
|
+
page,
|
|
927
|
+
perPage: perPageForResponse,
|
|
928
|
+
hasMore: false
|
|
929
|
+
};
|
|
930
|
+
}
|
|
876
931
|
const limitValue = perPageInput === false ? total : perPage;
|
|
877
|
-
|
|
932
|
+
selectQuery = selectQuery.orderBy(field, direction).limit(limitValue).offset(offset);
|
|
878
933
|
const results = await this.#db.executeQuery(selectQuery.build());
|
|
879
934
|
const threads = results.map(mapRowToStorageThreadType);
|
|
880
935
|
return {
|
|
@@ -885,13 +940,19 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
|
885
940
|
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
886
941
|
};
|
|
887
942
|
} catch (error$1) {
|
|
943
|
+
if (error$1 instanceof error.MastraError && error$1.category === error.ErrorCategory.USER) {
|
|
944
|
+
throw error$1;
|
|
945
|
+
}
|
|
888
946
|
const mastraError = new error.MastraError(
|
|
889
947
|
{
|
|
890
|
-
id: storage.createStorageErrorId("CLOUDFLARE_D1", "
|
|
948
|
+
id: storage.createStorageErrorId("CLOUDFLARE_D1", "LIST_THREADS", "FAILED"),
|
|
891
949
|
domain: error.ErrorDomain.STORAGE,
|
|
892
950
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
893
|
-
text: `Error
|
|
894
|
-
details: {
|
|
951
|
+
text: `Error listing threads: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
952
|
+
details: {
|
|
953
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
954
|
+
hasMetadataFilter: !!filter?.metadata
|
|
955
|
+
}
|
|
895
956
|
},
|
|
896
957
|
error$1
|
|
897
958
|
);
|