@mastra/pg 1.21.1 → 1.22.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/CHANGELOG.md +50 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +33 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +33 -15
- package/dist/index.js.map +1 -1
- package/dist/storage/db/sanitize-json.d.ts +11 -0
- package/dist/storage/db/sanitize-json.d.ts.map +1 -0
- package/dist/storage/domains/observability/v-next/scores.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/sql.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +2 -10
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/factory-storage.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @mastra/pg
|
|
2
2
|
|
|
3
|
+
## 1.22.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added native application collection counts so totals no longer load matching rows. ([#22021](https://github.com/mastra-ai/mastra/pull/22021))
|
|
8
|
+
|
|
9
|
+
**Before**
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const total = (await storage.ops.findMany('jobs', { status: 'failed' })).length;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**After**
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const total = await storage.ops.count?.('jobs', { status: 'failed' });
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Workflow snapshot upserts no longer overwrite a previously stored `resourceId` with NULL when a run is re-persisted without one (for example during resume). ([#22105](https://github.com/mastra-ai/mastra/pull/22105))
|
|
24
|
+
|
|
25
|
+
- Fix PostgreSQL observability writes failing on NUL characters and unpaired Unicode surrogates ([#21728](https://github.com/mastra-ai/mastra/pull/21728))
|
|
26
|
+
|
|
27
|
+
Span serialization truncated strings by UTF-16 code unit, so a cut inside an emoji left a lone surrogate that PostgreSQL rejected on the jsonb cast (`22P02`). NUL characters were rejected as well (`22P05`). Because observability events are inserted as a single multi-row statement, one malformed field discarded the entire batch.
|
|
28
|
+
|
|
29
|
+
Truncation now preserves complete surrogate pairs, and the v-next PostgreSQL observability encoder sanitizes NUL and unpaired surrogates before the jsonb cast, using the same sanitizer that workflow snapshots already rely on. Valid Unicode, including complete emoji, is preserved.
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [[`2c85f42`](https://github.com/mastra-ai/mastra/commit/2c85f428e04ccd63ea31a7ec80b5b327afdad555), [`11bbeb9`](https://github.com/mastra-ai/mastra/commit/11bbeb9b108ef2264e05acefc6dafb9cbb342921), [`1a485f3`](https://github.com/mastra-ai/mastra/commit/1a485f3538f5ec64d58bd8b5e1e99de0c695c87b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`8661d7d`](https://github.com/mastra-ai/mastra/commit/8661d7d7179f0a024456aabdd8679bcecd09ac28), [`575e343`](https://github.com/mastra-ai/mastra/commit/575e343900451021d96110916497d334af7bc252), [`cacb839`](https://github.com/mastra-ai/mastra/commit/cacb8392d9e74189b56d857290b0615f98a2683d), [`b47b26e`](https://github.com/mastra-ai/mastra/commit/b47b26e6fe95cb8a3482be2c5e52de157fe59d0b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`c46eb09`](https://github.com/mastra-ai/mastra/commit/c46eb09ce4987509af57a0ac582c61241a6dd2f1), [`30ed33e`](https://github.com/mastra-ai/mastra/commit/30ed33ee14084a26019aba15fceadda6d6ddefaf), [`91ad69d`](https://github.com/mastra-ai/mastra/commit/91ad69d64994c89199b0c55399e64ed91c61df2f), [`8dc408d`](https://github.com/mastra-ai/mastra/commit/8dc408d34438f9e13297f792c11a5cfd6cf952e1), [`c92def1`](https://github.com/mastra-ai/mastra/commit/c92def10a13c822972c96f0a4ca6ffc1f4258aed), [`c5eaec5`](https://github.com/mastra-ai/mastra/commit/c5eaec5a860d80d0e3805e67db0414b87ac8cbed), [`e66b2ba`](https://github.com/mastra-ai/mastra/commit/e66b2ba100db63eaeab6e21e1ea34b113f2ec781)]:
|
|
32
|
+
- @mastra/core@1.62.0-alpha.3
|
|
33
|
+
|
|
34
|
+
## 1.22.0-alpha.0
|
|
35
|
+
|
|
36
|
+
### Minor Changes
|
|
37
|
+
|
|
38
|
+
- Added support for filtering scores by metadata key-value pairs in listScores. ([#22047](https://github.com/mastra-ai/mastra/pull/22047))
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
const result = await storage.listScores({
|
|
42
|
+
filters: { metadata: { env: 'prod' } },
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Each top-level metadata key is matched with exact equality against the stored value. Nested objects and arrays compare structurally (key order doesn't matter) with no partial/subset matching, and an empty metadata filter is a no-op.
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [[`e737014`](https://github.com/mastra-ai/mastra/commit/e737014e0fc7035759762bb5b48baef1d6c0f6a7), [`d6ce34a`](https://github.com/mastra-ai/mastra/commit/d6ce34aeceb06ddf3d595a1eed5cc74f481a46a1), [`e6f8450`](https://github.com/mastra-ai/mastra/commit/e6f845074d478527026b18d85031b23353e1d0a4)]:
|
|
51
|
+
- @mastra/core@1.62.0-alpha.2
|
|
52
|
+
|
|
3
53
|
## 1.21.1
|
|
4
54
|
|
|
5
55
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -15260,6 +15260,20 @@ const COMPLEX_GROUP_BY_EXCLUDED = /* @__PURE__ */ new Set([
|
|
|
15260
15260
|
"requestContext"
|
|
15261
15261
|
]);
|
|
15262
15262
|
//#endregion
|
|
15263
|
+
//#region src/storage/db/sanitize-json.ts
|
|
15264
|
+
/**
|
|
15265
|
+
* Sanitizes JSON string for PostgreSQL jsonb:
|
|
15266
|
+
* - Removes problematic Unicode sequences:
|
|
15267
|
+
* - \u0000 (null character) - causes error 22P05 "unsupported Unicode escape sequence"
|
|
15268
|
+
* - \uD800-\uDFFF (unpaired surrogates) - causes "Unicode low surrogate must follow a high surrogate"
|
|
15269
|
+
* - \\uD800 (escaped-backslash + surrogate, e.g. from JS regex literals like [^\ud800-\udfff]):
|
|
15270
|
+
* removing just \uXXXX would leave a dangling backslash that creates a new invalid escape (e.g. \-)
|
|
15271
|
+
* - Escapes any remaining invalid JSON escape sequences (e.g. \v, \k, \-)
|
|
15272
|
+
*/
|
|
15273
|
+
function sanitizeJsonForPg(jsonString) {
|
|
15274
|
+
return jsonString.replace(/\\\\?u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "").replace(/(^|[^\\])(\\(?!["\\/bfnrtu]))/g, "$1\\\\");
|
|
15275
|
+
}
|
|
15276
|
+
//#endregion
|
|
15263
15277
|
//#region src/storage/domains/observability/v-next/sql.ts
|
|
15264
15278
|
/**
|
|
15265
15279
|
* SQL helpers for the v-next Postgres observability domain.
|
|
@@ -15272,10 +15286,16 @@ const COMPLEX_GROUP_BY_EXCLUDED = /* @__PURE__ */ new Set([
|
|
|
15272
15286
|
* Encode a JS value for a `$N::jsonb` cast. Always `JSON.stringify` so a
|
|
15273
15287
|
* plain string like `"hello"` becomes `"hello"` (a valid JSON scalar) and
|
|
15274
15288
|
* not the bare word `hello`, which Postgres rejects when cast to jsonb.
|
|
15289
|
+
*
|
|
15290
|
+
* The result is sanitized because Postgres rejects some sequences that are
|
|
15291
|
+
* legal in JSON: NUL (`\u0000`) fails with 22P05 and unpaired UTF-16
|
|
15292
|
+
* surrogates fail with 22P02. Inserts here are batched into a single
|
|
15293
|
+
* multi-row statement, so one bad value would otherwise reject the whole
|
|
15294
|
+
* batch of observability events.
|
|
15275
15295
|
*/
|
|
15276
15296
|
function encodeJsonb(value) {
|
|
15277
15297
|
if (value === null || value === void 0) return null;
|
|
15278
|
-
return JSON.stringify(value);
|
|
15298
|
+
return sanitizeJsonForPg(JSON.stringify(value));
|
|
15279
15299
|
}
|
|
15280
15300
|
/**
|
|
15281
15301
|
* Build a multi-row INSERT with explicit column types and ON CONFLICT DO NOTHING.
|
|
@@ -16112,6 +16132,10 @@ function applyScoreFilters(acc, filters) {
|
|
|
16112
16132
|
acc.conditions.push(`"scoreSource" = $${acc.next++}`);
|
|
16113
16133
|
acc.params.push(filters.scoreSource ?? filters.source);
|
|
16114
16134
|
}
|
|
16135
|
+
if (filters?.metadata && Object.keys(filters.metadata).length > 0) for (const [key, value] of Object.entries(filters.metadata)) {
|
|
16136
|
+
acc.conditions.push(`"metadata"->($${acc.next++}::text) = $${acc.next++}::jsonb`);
|
|
16137
|
+
acc.params.push(key, JSON.stringify(value ?? null));
|
|
16138
|
+
}
|
|
16115
16139
|
}
|
|
16116
16140
|
/** OLAP queries take an explicit scorerId / scoreSource pair as identity. */
|
|
16117
16141
|
function pushScoreIdentity(acc, scorerId, scoreSource) {
|
|
@@ -20497,18 +20521,6 @@ function workflowSnapshotStatusIndexSQL(indexName, schemaName) {
|
|
|
20497
20521
|
schemaName: getSchemaName(schemaName)
|
|
20498
20522
|
})} (workflow_name, (snapshot ->> 'status'), "createdAt" DESC)`;
|
|
20499
20523
|
}
|
|
20500
|
-
/**
|
|
20501
|
-
* Sanitizes JSON string for PostgreSQL jsonb:
|
|
20502
|
-
* - Removes problematic Unicode sequences:
|
|
20503
|
-
* - \u0000 (null character) - causes error 22P05 "unsupported Unicode escape sequence"
|
|
20504
|
-
* - \uD800-\uDFFF (unpaired surrogates) - causes "Unicode low surrogate must follow a high surrogate"
|
|
20505
|
-
* - \\uD800 (escaped-backslash + surrogate, e.g. from JS regex literals like [^\ud800-\udfff]):
|
|
20506
|
-
* removing just \uXXXX would leave a dangling backslash that creates a new invalid escape (e.g. \-)
|
|
20507
|
-
* - Escapes any remaining invalid JSON escape sequences (e.g. \v, \k, \-)
|
|
20508
|
-
*/
|
|
20509
|
-
function sanitizeJsonForPg(jsonString) {
|
|
20510
|
-
return jsonString.replace(/\\\\?u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "").replace(/(^|[^\\])(\\(?!["\\/bfnrtu]))/g, "$1\\\\");
|
|
20511
|
-
}
|
|
20512
20524
|
var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorage {
|
|
20513
20525
|
#db;
|
|
20514
20526
|
#schema;
|
|
@@ -20788,11 +20800,11 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
20788
20800
|
await this.#db.client.none(`INSERT INTO ${getTableName({
|
|
20789
20801
|
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
20790
20802
|
schemaName: getSchemaName(this.#schema)
|
|
20791
|
-
})}
|
|
20803
|
+
})} AS t
|
|
20792
20804
|
(workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt", "createdAtZ", "updatedAtZ")
|
|
20793
20805
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
20794
20806
|
ON CONFLICT (workflow_name, run_id) DO UPDATE
|
|
20795
|
-
SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6, "updatedAtZ" = $8`, [
|
|
20807
|
+
SET "resourceId" = COALESCE($3, t."resourceId"), snapshot = $4, "updatedAt" = $6, "updatedAtZ" = $8`, [
|
|
20796
20808
|
workflowName,
|
|
20797
20809
|
runId,
|
|
20798
20810
|
resourceId,
|
|
@@ -21750,6 +21762,12 @@ var PgFactoryStorageOps = class {
|
|
|
21750
21762
|
async findMany(collection, where, opts) {
|
|
21751
21763
|
return this.#select(this.#queryable, collection, where, opts);
|
|
21752
21764
|
}
|
|
21765
|
+
async count(collection, where) {
|
|
21766
|
+
const schema = this.#schema(collection);
|
|
21767
|
+
const filter = this.#buildWhere(schema, where);
|
|
21768
|
+
const result = await this.#queryable.query(`SELECT COUNT(*) AS count FROM "${schema.name}" WHERE ${filter.sql}`, filter.args);
|
|
21769
|
+
return Number(result.rows[0]?.count ?? 0);
|
|
21770
|
+
}
|
|
21753
21771
|
async insertOne(collection, row) {
|
|
21754
21772
|
const schema = this.#schema(collection);
|
|
21755
21773
|
const pk = primaryKeyOf(schema);
|