@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/dist/index.js CHANGED
@@ -15236,6 +15236,20 @@ const COMPLEX_GROUP_BY_EXCLUDED = /* @__PURE__ */ new Set([
15236
15236
  "requestContext"
15237
15237
  ]);
15238
15238
  //#endregion
15239
+ //#region src/storage/db/sanitize-json.ts
15240
+ /**
15241
+ * Sanitizes JSON string for PostgreSQL jsonb:
15242
+ * - Removes problematic Unicode sequences:
15243
+ * - \u0000 (null character) - causes error 22P05 "unsupported Unicode escape sequence"
15244
+ * - \uD800-\uDFFF (unpaired surrogates) - causes "Unicode low surrogate must follow a high surrogate"
15245
+ * - \\uD800 (escaped-backslash + surrogate, e.g. from JS regex literals like [^\ud800-\udfff]):
15246
+ * removing just \uXXXX would leave a dangling backslash that creates a new invalid escape (e.g. \-)
15247
+ * - Escapes any remaining invalid JSON escape sequences (e.g. \v, \k, \-)
15248
+ */
15249
+ function sanitizeJsonForPg(jsonString) {
15250
+ return jsonString.replace(/\\\\?u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "").replace(/(^|[^\\])(\\(?!["\\/bfnrtu]))/g, "$1\\\\");
15251
+ }
15252
+ //#endregion
15239
15253
  //#region src/storage/domains/observability/v-next/sql.ts
15240
15254
  /**
15241
15255
  * SQL helpers for the v-next Postgres observability domain.
@@ -15248,10 +15262,16 @@ const COMPLEX_GROUP_BY_EXCLUDED = /* @__PURE__ */ new Set([
15248
15262
  * Encode a JS value for a `$N::jsonb` cast. Always `JSON.stringify` so a
15249
15263
  * plain string like `"hello"` becomes `"hello"` (a valid JSON scalar) and
15250
15264
  * not the bare word `hello`, which Postgres rejects when cast to jsonb.
15265
+ *
15266
+ * The result is sanitized because Postgres rejects some sequences that are
15267
+ * legal in JSON: NUL (`\u0000`) fails with 22P05 and unpaired UTF-16
15268
+ * surrogates fail with 22P02. Inserts here are batched into a single
15269
+ * multi-row statement, so one bad value would otherwise reject the whole
15270
+ * batch of observability events.
15251
15271
  */
15252
15272
  function encodeJsonb(value) {
15253
15273
  if (value === null || value === void 0) return null;
15254
- return JSON.stringify(value);
15274
+ return sanitizeJsonForPg(JSON.stringify(value));
15255
15275
  }
15256
15276
  /**
15257
15277
  * Build a multi-row INSERT with explicit column types and ON CONFLICT DO NOTHING.
@@ -16088,6 +16108,10 @@ function applyScoreFilters(acc, filters) {
16088
16108
  acc.conditions.push(`"scoreSource" = $${acc.next++}`);
16089
16109
  acc.params.push(filters.scoreSource ?? filters.source);
16090
16110
  }
16111
+ if (filters?.metadata && Object.keys(filters.metadata).length > 0) for (const [key, value] of Object.entries(filters.metadata)) {
16112
+ acc.conditions.push(`"metadata"->($${acc.next++}::text) = $${acc.next++}::jsonb`);
16113
+ acc.params.push(key, JSON.stringify(value ?? null));
16114
+ }
16091
16115
  }
16092
16116
  /** OLAP queries take an explicit scorerId / scoreSource pair as identity. */
16093
16117
  function pushScoreIdentity(acc, scorerId, scoreSource) {
@@ -20473,18 +20497,6 @@ function workflowSnapshotStatusIndexSQL(indexName, schemaName) {
20473
20497
  schemaName: getSchemaName(schemaName)
20474
20498
  })} (workflow_name, (snapshot ->> 'status'), "createdAt" DESC)`;
20475
20499
  }
20476
- /**
20477
- * Sanitizes JSON string for PostgreSQL jsonb:
20478
- * - Removes problematic Unicode sequences:
20479
- * - \u0000 (null character) - causes error 22P05 "unsupported Unicode escape sequence"
20480
- * - \uD800-\uDFFF (unpaired surrogates) - causes "Unicode low surrogate must follow a high surrogate"
20481
- * - \\uD800 (escaped-backslash + surrogate, e.g. from JS regex literals like [^\ud800-\udfff]):
20482
- * removing just \uXXXX would leave a dangling backslash that creates a new invalid escape (e.g. \-)
20483
- * - Escapes any remaining invalid JSON escape sequences (e.g. \v, \k, \-)
20484
- */
20485
- function sanitizeJsonForPg(jsonString) {
20486
- return jsonString.replace(/\\\\?u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "").replace(/(^|[^\\])(\\(?!["\\/bfnrtu]))/g, "$1\\\\");
20487
- }
20488
20500
  var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
20489
20501
  #db;
20490
20502
  #schema;
@@ -20764,11 +20776,11 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
20764
20776
  await this.#db.client.none(`INSERT INTO ${getTableName({
20765
20777
  indexName: TABLE_WORKFLOW_SNAPSHOT,
20766
20778
  schemaName: getSchemaName(this.#schema)
20767
- })}
20779
+ })} AS t
20768
20780
  (workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt", "createdAtZ", "updatedAtZ")
20769
20781
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
20770
20782
  ON CONFLICT (workflow_name, run_id) DO UPDATE
20771
- SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6, "updatedAtZ" = $8`, [
20783
+ SET "resourceId" = COALESCE($3, t."resourceId"), snapshot = $4, "updatedAt" = $6, "updatedAtZ" = $8`, [
20772
20784
  workflowName,
20773
20785
  runId,
20774
20786
  resourceId,
@@ -21726,6 +21738,12 @@ var PgFactoryStorageOps = class {
21726
21738
  async findMany(collection, where, opts) {
21727
21739
  return this.#select(this.#queryable, collection, where, opts);
21728
21740
  }
21741
+ async count(collection, where) {
21742
+ const schema = this.#schema(collection);
21743
+ const filter = this.#buildWhere(schema, where);
21744
+ const result = await this.#queryable.query(`SELECT COUNT(*) AS count FROM "${schema.name}" WHERE ${filter.sql}`, filter.args);
21745
+ return Number(result.rows[0]?.count ?? 0);
21746
+ }
21729
21747
  async insertOne(collection, row) {
21730
21748
  const schema = this.#schema(collection);
21731
21749
  const pk = primaryKeyOf(schema);