@mastra/pg 1.0.0-beta.12 → 1.0.0-beta.14

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
@@ -2078,7 +2078,7 @@ var PgDB = class extends MastraBase {
2078
2078
  SELECT 1 FROM information_schema.tables
2079
2079
  WHERE table_schema = $1 AND table_name = $2
2080
2080
  )`,
2081
- [this.schemaName || "mastra", tableName]
2081
+ [this.schemaName || "public", tableName]
2082
2082
  );
2083
2083
  if (tableExists?.exists) {
2084
2084
  await this.client.none(`TRUNCATE TABLE ${tableNameWithSchema} CASCADE`);
@@ -3195,27 +3195,52 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
3195
3195
  );
3196
3196
  }
3197
3197
  }
3198
- async listThreadsByResourceId(args) {
3199
- const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
3200
- if (page < 0) {
3198
+ async listThreads(args) {
3199
+ const { page = 0, perPage: perPageInput, orderBy, filter } = args;
3200
+ try {
3201
+ this.validatePaginationInput(page, perPageInput ?? 100);
3202
+ } catch (error) {
3201
3203
  throw new MastraError({
3202
- id: createStorageErrorId("PG", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
3204
+ id: createStorageErrorId("PG", "LIST_THREADS", "INVALID_PAGE"),
3203
3205
  domain: ErrorDomain.STORAGE,
3204
3206
  category: ErrorCategory.USER,
3205
- text: "Page number must be non-negative",
3206
- details: {
3207
- resourceId,
3208
- page
3209
- }
3207
+ text: error instanceof Error ? error.message : "Invalid pagination parameters",
3208
+ details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
3210
3209
  });
3211
3210
  }
3212
- const { field, direction } = this.parseOrderBy(orderBy);
3213
3211
  const perPage = normalizePerPage(perPageInput, 100);
3212
+ try {
3213
+ this.validateMetadataKeys(filter?.metadata);
3214
+ } catch (error) {
3215
+ throw new MastraError({
3216
+ id: createStorageErrorId("PG", "LIST_THREADS", "INVALID_METADATA_KEY"),
3217
+ domain: ErrorDomain.STORAGE,
3218
+ category: ErrorCategory.USER,
3219
+ text: error instanceof Error ? error.message : "Invalid metadata key",
3220
+ details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
3221
+ });
3222
+ }
3223
+ const { field, direction } = this.parseOrderBy(orderBy);
3214
3224
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
3215
3225
  try {
3216
3226
  const tableName = getTableName3({ indexName: TABLE_THREADS, schemaName: getSchemaName3(this.#schema) });
3217
- const baseQuery = `FROM ${tableName} WHERE "resourceId" = $1`;
3218
- const queryParams = [resourceId];
3227
+ const whereClauses = [];
3228
+ const queryParams = [];
3229
+ let paramIndex = 1;
3230
+ if (filter?.resourceId) {
3231
+ whereClauses.push(`"resourceId" = $${paramIndex}`);
3232
+ queryParams.push(filter.resourceId);
3233
+ paramIndex++;
3234
+ }
3235
+ if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
3236
+ for (const [key, value] of Object.entries(filter.metadata)) {
3237
+ whereClauses.push(`metadata::jsonb @> $${paramIndex}::jsonb`);
3238
+ queryParams.push(JSON.stringify({ [key]: value }));
3239
+ paramIndex++;
3240
+ }
3241
+ }
3242
+ const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
3243
+ const baseQuery = `FROM ${tableName} ${whereClause}`;
3219
3244
  const countQuery = `SELECT COUNT(*) ${baseQuery}`;
3220
3245
  const countResult = await this.#db.client.one(countQuery, queryParams);
3221
3246
  const total = parseInt(countResult.count, 10);
@@ -3229,7 +3254,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
3229
3254
  };
3230
3255
  }
3231
3256
  const limitValue = perPageInput === false ? total : perPage;
3232
- const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`;
3257
+ const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
3233
3258
  const rows = await this.#db.client.manyOrNone(
3234
3259
  dataQuery,
3235
3260
  [...queryParams, limitValue, offset]
@@ -3253,11 +3278,12 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
3253
3278
  } catch (error) {
3254
3279
  const mastraError = new MastraError(
3255
3280
  {
3256
- id: createStorageErrorId("PG", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
3281
+ id: createStorageErrorId("PG", "LIST_THREADS", "FAILED"),
3257
3282
  domain: ErrorDomain.STORAGE,
3258
3283
  category: ErrorCategory.THIRD_PARTY,
3259
3284
  details: {
3260
- resourceId,
3285
+ ...filter?.resourceId && { resourceId: filter.resourceId },
3286
+ hasMetadataFilter: !!filter?.metadata,
3261
3287
  page
3262
3288
  }
3263
3289
  },
@@ -4733,6 +4759,11 @@ var ScoresPG = class _ScoresPG extends ScoresStorage {
4733
4759
  }
4734
4760
  async init() {
4735
4761
  await this.#db.createTable({ tableName: TABLE_SCORERS, schema: TABLE_SCHEMAS[TABLE_SCORERS] });
4762
+ await this.#db.alterTable({
4763
+ tableName: TABLE_SCORERS,
4764
+ schema: TABLE_SCHEMAS[TABLE_SCORERS],
4765
+ ifNotExists: ["spanId", "requestContext"]
4766
+ });
4736
4767
  await this.createDefaultIndexes();
4737
4768
  await this.createCustomIndexes();
4738
4769
  }
@@ -5084,23 +5115,8 @@ function getTableName5({ indexName, schemaName }) {
5084
5115
  const quotedIndexName = `"${indexName}"`;
5085
5116
  return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
5086
5117
  }
5087
- function parseWorkflowRun(row) {
5088
- let parsedSnapshot = row.snapshot;
5089
- if (typeof parsedSnapshot === "string") {
5090
- try {
5091
- parsedSnapshot = JSON.parse(row.snapshot);
5092
- } catch (e) {
5093
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
5094
- }
5095
- }
5096
- return {
5097
- workflowName: row.workflow_name,
5098
- runId: row.run_id,
5099
- snapshot: parsedSnapshot,
5100
- resourceId: row.resourceId,
5101
- createdAt: new Date(row.createdAtZ || row.createdAt),
5102
- updatedAt: new Date(row.updatedAtZ || row.updatedAt)
5103
- };
5118
+ function sanitizeJsonForPg(jsonString) {
5119
+ return jsonString.replace(/\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "");
5104
5120
  }
5105
5121
  var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5106
5122
  #db;
@@ -5117,6 +5133,24 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5117
5133
  this.#skipDefaultIndexes = skipDefaultIndexes;
5118
5134
  this.#indexes = indexes?.filter((idx) => _WorkflowsPG.MANAGED_TABLES.includes(idx.table));
5119
5135
  }
5136
+ parseWorkflowRun(row) {
5137
+ let parsedSnapshot = row.snapshot;
5138
+ if (typeof parsedSnapshot === "string") {
5139
+ try {
5140
+ parsedSnapshot = JSON.parse(row.snapshot);
5141
+ } catch (e) {
5142
+ this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
5143
+ }
5144
+ }
5145
+ return {
5146
+ workflowName: row.workflow_name,
5147
+ runId: row.run_id,
5148
+ snapshot: parsedSnapshot,
5149
+ resourceId: row.resourceId,
5150
+ createdAt: new Date(row.createdAtZ || row.createdAt),
5151
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
5152
+ };
5153
+ }
5120
5154
  /**
5121
5155
  * Returns default index definitions for the workflows domain tables.
5122
5156
  * Currently no default indexes are defined for workflows.
@@ -5189,12 +5223,13 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5189
5223
  const now = /* @__PURE__ */ new Date();
5190
5224
  const createdAtValue = createdAt ? createdAt : now;
5191
5225
  const updatedAtValue = updatedAt ? updatedAt : now;
5226
+ const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(snapshot));
5192
5227
  await this.#db.client.none(
5193
5228
  `INSERT INTO ${getTableName5({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} (workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt")
5194
5229
  VALUES ($1, $2, $3, $4, $5, $6)
5195
5230
  ON CONFLICT (workflow_name, run_id) DO UPDATE
5196
5231
  SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6`,
5197
- [workflowName, runId, resourceId, JSON.stringify(snapshot), createdAtValue, updatedAtValue]
5232
+ [workflowName, runId, resourceId, sanitizedSnapshot, createdAtValue, updatedAtValue]
5198
5233
  );
5199
5234
  } catch (error) {
5200
5235
  throw new MastraError(
@@ -5257,7 +5292,7 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5257
5292
  if (!result) {
5258
5293
  return null;
5259
5294
  }
5260
- return parseWorkflowRun(result);
5295
+ return this.parseWorkflowRun(result);
5261
5296
  } catch (error) {
5262
5297
  throw new MastraError(
5263
5298
  {
@@ -5313,7 +5348,9 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5313
5348
  paramIndex++;
5314
5349
  }
5315
5350
  if (status) {
5316
- conditions.push(`snapshot::jsonb ->> 'status' = $${paramIndex}`);
5351
+ conditions.push(
5352
+ `regexp_replace(snapshot::text, '\\\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})', '', 'g')::jsonb ->> 'status' = $${paramIndex}`
5353
+ );
5317
5354
  values.push(status);
5318
5355
  paramIndex++;
5319
5356
  }
@@ -5358,7 +5395,7 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
5358
5395
  const queryValues = usePagination ? [...values, normalizedPerPage, offset] : values;
5359
5396
  const result = await this.#db.client.manyOrNone(query, queryValues);
5360
5397
  const runs = (result || []).map((row) => {
5361
- return parseWorkflowRun(row);
5398
+ return this.parseWorkflowRun(row);
5362
5399
  });
5363
5400
  return { runs, total: total || runs.length };
5364
5401
  } catch (error) {
@@ -5391,7 +5428,7 @@ var PostgresStore = class extends MastraStorage {
5391
5428
  try {
5392
5429
  validateConfig("PostgresStore", config);
5393
5430
  super({ id: config.id, name: "PostgresStore", disableInit: config.disableInit });
5394
- this.schema = config.schemaName || "public";
5431
+ this.schema = parseSqlIdentifier(config.schemaName || "public", "schema name");
5395
5432
  if (isPoolConfig(config)) {
5396
5433
  this.#pool = config.pool;
5397
5434
  this.#ownsPool = false;