@mastra/pg 1.1.0-alpha.0 → 1.1.0-alpha.2
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 +36 -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 +182 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +182 -98
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3119,10 +3119,124 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3119
3119
|
}
|
|
3120
3120
|
}
|
|
3121
3121
|
async init() {
|
|
3122
|
+
await this.#migrateFromLegacySchema();
|
|
3123
|
+
await this.#migrateVersionsSchema();
|
|
3122
3124
|
await this.#db.createTable({ tableName: TABLE_AGENTS, schema: TABLE_SCHEMAS[TABLE_AGENTS] });
|
|
3123
3125
|
await this.#db.createTable({ tableName: TABLE_AGENT_VERSIONS, schema: TABLE_SCHEMAS[TABLE_AGENT_VERSIONS] });
|
|
3126
|
+
await this.#db.alterTable({
|
|
3127
|
+
tableName: TABLE_AGENTS,
|
|
3128
|
+
schema: TABLE_SCHEMAS[TABLE_AGENTS],
|
|
3129
|
+
ifNotExists: ["status", "authorId"]
|
|
3130
|
+
});
|
|
3124
3131
|
await this.createDefaultIndexes();
|
|
3125
3132
|
await this.createCustomIndexes();
|
|
3133
|
+
await this.#cleanupStaleDrafts();
|
|
3134
|
+
}
|
|
3135
|
+
/**
|
|
3136
|
+
* Migrates from the legacy flat agent schema (where config fields like name, instructions, model
|
|
3137
|
+
* were stored directly on mastra_agents) to the new versioned schema (thin agent record + versions table).
|
|
3138
|
+
*/
|
|
3139
|
+
async #migrateFromLegacySchema() {
|
|
3140
|
+
const fullTableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
|
|
3141
|
+
const fullVersionsTableName = getTableName2({
|
|
3142
|
+
indexName: TABLE_AGENT_VERSIONS,
|
|
3143
|
+
schemaName: getSchemaName2(this.#schema)
|
|
3144
|
+
});
|
|
3145
|
+
const legacyTableName = getTableName2({
|
|
3146
|
+
indexName: `${TABLE_AGENTS}_legacy`,
|
|
3147
|
+
schemaName: getSchemaName2(this.#schema)
|
|
3148
|
+
});
|
|
3149
|
+
const hasLegacyColumns = await this.#db.hasColumn(TABLE_AGENTS, "name");
|
|
3150
|
+
if (hasLegacyColumns) {
|
|
3151
|
+
await this.#db.client.none(`ALTER TABLE ${fullTableName} RENAME TO "${TABLE_AGENTS}_legacy"`);
|
|
3152
|
+
await this.#db.client.none(`DROP TABLE IF EXISTS ${fullVersionsTableName}`);
|
|
3153
|
+
}
|
|
3154
|
+
const legacyExists = await this.#db.hasColumn(`${TABLE_AGENTS}_legacy`, "name");
|
|
3155
|
+
if (!legacyExists) return;
|
|
3156
|
+
const oldAgents = await this.#db.client.manyOrNone(`SELECT * FROM ${legacyTableName}`);
|
|
3157
|
+
await this.#db.createTable({ tableName: TABLE_AGENTS, schema: TABLE_SCHEMAS[TABLE_AGENTS] });
|
|
3158
|
+
await this.#db.createTable({ tableName: TABLE_AGENT_VERSIONS, schema: TABLE_SCHEMAS[TABLE_AGENT_VERSIONS] });
|
|
3159
|
+
for (const row of oldAgents) {
|
|
3160
|
+
const agentId = row.id;
|
|
3161
|
+
if (!agentId) continue;
|
|
3162
|
+
const versionId = crypto.randomUUID();
|
|
3163
|
+
const now = /* @__PURE__ */ new Date();
|
|
3164
|
+
await this.#db.client.none(
|
|
3165
|
+
`INSERT INTO ${fullTableName} (id, status, "activeVersionId", "authorId", metadata, "createdAt", "updatedAt")
|
|
3166
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
3167
|
+
ON CONFLICT (id) DO NOTHING`,
|
|
3168
|
+
[
|
|
3169
|
+
agentId,
|
|
3170
|
+
"published",
|
|
3171
|
+
versionId,
|
|
3172
|
+
row.ownerId ?? row.authorId ?? null,
|
|
3173
|
+
row.metadata ? JSON.stringify(row.metadata) : null,
|
|
3174
|
+
row.createdAt ?? now,
|
|
3175
|
+
row.updatedAt ?? now
|
|
3176
|
+
]
|
|
3177
|
+
);
|
|
3178
|
+
await this.#db.client.none(
|
|
3179
|
+
`INSERT INTO ${fullVersionsTableName}
|
|
3180
|
+
(id, "agentId", "versionNumber", name, description, instructions, model, tools,
|
|
3181
|
+
"defaultOptions", workflows, agents, "integrationTools", "inputProcessors",
|
|
3182
|
+
"outputProcessors", memory, scorers, "changedFields", "changeMessage", "createdAt")
|
|
3183
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19)
|
|
3184
|
+
ON CONFLICT (id) DO NOTHING`,
|
|
3185
|
+
[
|
|
3186
|
+
versionId,
|
|
3187
|
+
agentId,
|
|
3188
|
+
1,
|
|
3189
|
+
row.name ?? agentId,
|
|
3190
|
+
row.description ?? null,
|
|
3191
|
+
row.instructions ?? "",
|
|
3192
|
+
row.model ? JSON.stringify(row.model) : "{}",
|
|
3193
|
+
row.tools ? JSON.stringify(row.tools) : null,
|
|
3194
|
+
row.defaultOptions ? JSON.stringify(row.defaultOptions) : null,
|
|
3195
|
+
row.workflows ? JSON.stringify(row.workflows) : null,
|
|
3196
|
+
row.agents ? JSON.stringify(row.agents) : null,
|
|
3197
|
+
row.integrationTools ? JSON.stringify(row.integrationTools) : null,
|
|
3198
|
+
row.inputProcessors ? JSON.stringify(row.inputProcessors) : null,
|
|
3199
|
+
row.outputProcessors ? JSON.stringify(row.outputProcessors) : null,
|
|
3200
|
+
row.memory ? JSON.stringify(row.memory) : null,
|
|
3201
|
+
row.scorers ? JSON.stringify(row.scorers) : null,
|
|
3202
|
+
null,
|
|
3203
|
+
"Migrated from legacy schema",
|
|
3204
|
+
row.createdAt ?? now
|
|
3205
|
+
]
|
|
3206
|
+
);
|
|
3207
|
+
}
|
|
3208
|
+
await this.#db.client.none(`DROP TABLE IF EXISTS ${legacyTableName}`);
|
|
3209
|
+
}
|
|
3210
|
+
/**
|
|
3211
|
+
* Migrates the agent_versions table from the old snapshot-based schema (single `snapshot` JSON column)
|
|
3212
|
+
* to the new flat schema (individual config columns). This handles the case where the agents table
|
|
3213
|
+
* was already migrated but the versions table still has the old schema.
|
|
3214
|
+
*/
|
|
3215
|
+
async #migrateVersionsSchema() {
|
|
3216
|
+
const hasSnapshotColumn = await this.#db.hasColumn(TABLE_AGENT_VERSIONS, "snapshot");
|
|
3217
|
+
if (!hasSnapshotColumn) return;
|
|
3218
|
+
const fullVersionsTableName = getTableName2({
|
|
3219
|
+
indexName: TABLE_AGENT_VERSIONS,
|
|
3220
|
+
schemaName: getSchemaName2(this.#schema)
|
|
3221
|
+
});
|
|
3222
|
+
const legacyTableName = getTableName2({
|
|
3223
|
+
indexName: `${TABLE_AGENTS}_legacy`,
|
|
3224
|
+
schemaName: getSchemaName2(this.#schema)
|
|
3225
|
+
});
|
|
3226
|
+
await this.#db.client.none(`DROP TABLE IF EXISTS ${fullVersionsTableName}`);
|
|
3227
|
+
await this.#db.client.none(`DROP TABLE IF EXISTS ${legacyTableName}`);
|
|
3228
|
+
}
|
|
3229
|
+
/**
|
|
3230
|
+
* Removes stale draft agent records that have no activeVersionId.
|
|
3231
|
+
* These are left behind when createAgent partially fails (inserts thin record
|
|
3232
|
+
* but fails to create the version due to schema mismatch).
|
|
3233
|
+
*/
|
|
3234
|
+
async #cleanupStaleDrafts() {
|
|
3235
|
+
try {
|
|
3236
|
+
const fullTableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
|
|
3237
|
+
await this.#db.client.none(`DELETE FROM ${fullTableName} WHERE status = 'draft' AND "activeVersionId" IS NULL`);
|
|
3238
|
+
} catch {
|
|
3239
|
+
}
|
|
3126
3240
|
}
|
|
3127
3241
|
/**
|
|
3128
3242
|
* Creates custom user-defined indexes for this domain's tables.
|
|
@@ -3170,22 +3284,10 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3170
3284
|
parseRow(row) {
|
|
3171
3285
|
return {
|
|
3172
3286
|
id: row.id,
|
|
3173
|
-
|
|
3174
|
-
description: row.description,
|
|
3175
|
-
instructions: row.instructions,
|
|
3176
|
-
model: this.parseJson(row.model, "model"),
|
|
3177
|
-
tools: this.parseJson(row.tools, "tools"),
|
|
3178
|
-
defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
|
|
3179
|
-
workflows: this.parseJson(row.workflows, "workflows"),
|
|
3180
|
-
agents: this.parseJson(row.agents, "agents"),
|
|
3181
|
-
integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
|
|
3182
|
-
inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
|
|
3183
|
-
outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
|
|
3184
|
-
memory: this.parseJson(row.memory, "memory"),
|
|
3185
|
-
scorers: this.parseJson(row.scorers, "scorers"),
|
|
3186
|
-
metadata: this.parseJson(row.metadata, "metadata"),
|
|
3187
|
-
ownerId: row.ownerId,
|
|
3287
|
+
status: row.status,
|
|
3188
3288
|
activeVersionId: row.activeVersionId,
|
|
3289
|
+
authorId: row.authorId,
|
|
3290
|
+
metadata: this.parseJson(row.metadata, "metadata"),
|
|
3189
3291
|
createdAt: row.createdAtZ || row.createdAt,
|
|
3190
3292
|
updatedAt: row.updatedAtZ || row.updatedAt
|
|
3191
3293
|
};
|
|
@@ -3212,43 +3314,48 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3212
3314
|
}
|
|
3213
3315
|
async createAgent({ agent }) {
|
|
3214
3316
|
try {
|
|
3215
|
-
const
|
|
3317
|
+
const agentsTable = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
|
|
3216
3318
|
const now = /* @__PURE__ */ new Date();
|
|
3217
3319
|
const nowIso = now.toISOString();
|
|
3218
3320
|
await this.#db.client.none(
|
|
3219
|
-
`INSERT INTO ${
|
|
3220
|
-
id,
|
|
3221
|
-
"
|
|
3222
|
-
"inputProcessors", "outputProcessors", memory, scorers, metadata,
|
|
3223
|
-
"ownerId", "activeVersionId",
|
|
3321
|
+
`INSERT INTO ${agentsTable} (
|
|
3322
|
+
id, status, "authorId", metadata,
|
|
3323
|
+
"activeVersionId",
|
|
3224
3324
|
"createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
|
|
3225
|
-
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9
|
|
3325
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
|
3226
3326
|
[
|
|
3227
3327
|
agent.id,
|
|
3228
|
-
|
|
3229
|
-
agent.
|
|
3230
|
-
agent.instructions,
|
|
3231
|
-
JSON.stringify(agent.model),
|
|
3232
|
-
agent.tools ? JSON.stringify(agent.tools) : null,
|
|
3233
|
-
agent.defaultOptions ? JSON.stringify(agent.defaultOptions) : null,
|
|
3234
|
-
agent.workflows ? JSON.stringify(agent.workflows) : null,
|
|
3235
|
-
agent.agents ? JSON.stringify(agent.agents) : null,
|
|
3236
|
-
agent.integrationTools ? JSON.stringify(agent.integrationTools) : null,
|
|
3237
|
-
agent.inputProcessors ? JSON.stringify(agent.inputProcessors) : null,
|
|
3238
|
-
agent.outputProcessors ? JSON.stringify(agent.outputProcessors) : null,
|
|
3239
|
-
agent.memory ? JSON.stringify(agent.memory) : null,
|
|
3240
|
-
agent.scorers ? JSON.stringify(agent.scorers) : null,
|
|
3328
|
+
"draft",
|
|
3329
|
+
agent.authorId ?? null,
|
|
3241
3330
|
agent.metadata ? JSON.stringify(agent.metadata) : null,
|
|
3242
|
-
|
|
3243
|
-
|
|
3331
|
+
null,
|
|
3332
|
+
// activeVersionId starts as null
|
|
3244
3333
|
nowIso,
|
|
3245
3334
|
nowIso,
|
|
3246
3335
|
nowIso,
|
|
3247
3336
|
nowIso
|
|
3248
3337
|
]
|
|
3249
3338
|
);
|
|
3339
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = agent;
|
|
3340
|
+
const versionId = crypto.randomUUID();
|
|
3341
|
+
await this.createVersion({
|
|
3342
|
+
id: versionId,
|
|
3343
|
+
agentId: agent.id,
|
|
3344
|
+
versionNumber: 1,
|
|
3345
|
+
...snapshotConfig,
|
|
3346
|
+
changedFields: Object.keys(snapshotConfig),
|
|
3347
|
+
changeMessage: "Initial version"
|
|
3348
|
+
});
|
|
3349
|
+
await this.#db.client.none(
|
|
3350
|
+
`UPDATE ${agentsTable} SET "activeVersionId" = $1, status = $2, "updatedAt" = $3, "updatedAtZ" = $4 WHERE id = $5`,
|
|
3351
|
+
[versionId, "published", nowIso, nowIso, agent.id]
|
|
3352
|
+
);
|
|
3250
3353
|
return {
|
|
3251
|
-
|
|
3354
|
+
id: agent.id,
|
|
3355
|
+
status: "published",
|
|
3356
|
+
activeVersionId: versionId,
|
|
3357
|
+
authorId: agent.authorId,
|
|
3358
|
+
metadata: agent.metadata,
|
|
3252
3359
|
createdAt: now,
|
|
3253
3360
|
updatedAt: now
|
|
3254
3361
|
};
|
|
@@ -3280,65 +3387,15 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3280
3387
|
const setClauses = [];
|
|
3281
3388
|
const values = [];
|
|
3282
3389
|
let paramIndex = 1;
|
|
3283
|
-
if (updates.
|
|
3284
|
-
setClauses.push(`
|
|
3285
|
-
values.push(updates.
|
|
3286
|
-
}
|
|
3287
|
-
if (updates.description !== void 0) {
|
|
3288
|
-
setClauses.push(`description = $${paramIndex++}`);
|
|
3289
|
-
values.push(updates.description);
|
|
3290
|
-
}
|
|
3291
|
-
if (updates.instructions !== void 0) {
|
|
3292
|
-
setClauses.push(`instructions = $${paramIndex++}`);
|
|
3293
|
-
values.push(updates.instructions);
|
|
3294
|
-
}
|
|
3295
|
-
if (updates.model !== void 0) {
|
|
3296
|
-
setClauses.push(`model = $${paramIndex++}`);
|
|
3297
|
-
values.push(JSON.stringify(updates.model));
|
|
3298
|
-
}
|
|
3299
|
-
if (updates.tools !== void 0) {
|
|
3300
|
-
setClauses.push(`tools = $${paramIndex++}`);
|
|
3301
|
-
values.push(JSON.stringify(updates.tools));
|
|
3302
|
-
}
|
|
3303
|
-
if (updates.defaultOptions !== void 0) {
|
|
3304
|
-
setClauses.push(`"defaultOptions" = $${paramIndex++}`);
|
|
3305
|
-
values.push(JSON.stringify(updates.defaultOptions));
|
|
3306
|
-
}
|
|
3307
|
-
if (updates.workflows !== void 0) {
|
|
3308
|
-
setClauses.push(`workflows = $${paramIndex++}`);
|
|
3309
|
-
values.push(JSON.stringify(updates.workflows));
|
|
3310
|
-
}
|
|
3311
|
-
if (updates.agents !== void 0) {
|
|
3312
|
-
setClauses.push(`agents = $${paramIndex++}`);
|
|
3313
|
-
values.push(JSON.stringify(updates.agents));
|
|
3314
|
-
}
|
|
3315
|
-
if (updates.inputProcessors !== void 0) {
|
|
3316
|
-
setClauses.push(`"inputProcessors" = $${paramIndex++}`);
|
|
3317
|
-
values.push(JSON.stringify(updates.inputProcessors));
|
|
3318
|
-
}
|
|
3319
|
-
if (updates.outputProcessors !== void 0) {
|
|
3320
|
-
setClauses.push(`"outputProcessors" = $${paramIndex++}`);
|
|
3321
|
-
values.push(JSON.stringify(updates.outputProcessors));
|
|
3322
|
-
}
|
|
3323
|
-
if (updates.memory !== void 0) {
|
|
3324
|
-
setClauses.push(`memory = $${paramIndex++}`);
|
|
3325
|
-
values.push(JSON.stringify(updates.memory));
|
|
3326
|
-
}
|
|
3327
|
-
if (updates.scorers !== void 0) {
|
|
3328
|
-
setClauses.push(`scorers = $${paramIndex++}`);
|
|
3329
|
-
values.push(JSON.stringify(updates.scorers));
|
|
3330
|
-
}
|
|
3331
|
-
if (updates.integrationTools !== void 0) {
|
|
3332
|
-
setClauses.push(`"integrationTools" = $${paramIndex++}`);
|
|
3333
|
-
values.push(JSON.stringify(updates.integrationTools));
|
|
3334
|
-
}
|
|
3335
|
-
if (updates.ownerId !== void 0) {
|
|
3336
|
-
setClauses.push(`"ownerId" = $${paramIndex++}`);
|
|
3337
|
-
values.push(updates.ownerId);
|
|
3390
|
+
if (updates.authorId !== void 0) {
|
|
3391
|
+
setClauses.push(`"authorId" = $${paramIndex++}`);
|
|
3392
|
+
values.push(updates.authorId);
|
|
3338
3393
|
}
|
|
3339
3394
|
if (updates.activeVersionId !== void 0) {
|
|
3340
3395
|
setClauses.push(`"activeVersionId" = $${paramIndex++}`);
|
|
3341
3396
|
values.push(updates.activeVersionId);
|
|
3397
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
3398
|
+
values.push("published");
|
|
3342
3399
|
}
|
|
3343
3400
|
if (updates.metadata !== void 0) {
|
|
3344
3401
|
const mergedMetadata = { ...existingAgent.metadata, ...updates.metadata };
|
|
@@ -3463,14 +3520,30 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3463
3520
|
const nowIso = now.toISOString();
|
|
3464
3521
|
await this.#db.client.none(
|
|
3465
3522
|
`INSERT INTO ${tableName} (
|
|
3466
|
-
id, "agentId", "versionNumber",
|
|
3467
|
-
|
|
3523
|
+
id, "agentId", "versionNumber",
|
|
3524
|
+
name, description, instructions, model, tools,
|
|
3525
|
+
"defaultOptions", workflows, agents, "integrationTools",
|
|
3526
|
+
"inputProcessors", "outputProcessors", memory, scorers,
|
|
3527
|
+
"changedFields", "changeMessage",
|
|
3528
|
+
"createdAt", "createdAtZ"
|
|
3529
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)`,
|
|
3468
3530
|
[
|
|
3469
3531
|
input.id,
|
|
3470
3532
|
input.agentId,
|
|
3471
3533
|
input.versionNumber,
|
|
3472
|
-
input.name
|
|
3473
|
-
|
|
3534
|
+
input.name,
|
|
3535
|
+
input.description ?? null,
|
|
3536
|
+
input.instructions,
|
|
3537
|
+
JSON.stringify(input.model),
|
|
3538
|
+
input.tools ? JSON.stringify(input.tools) : null,
|
|
3539
|
+
input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
|
|
3540
|
+
input.workflows ? JSON.stringify(input.workflows) : null,
|
|
3541
|
+
input.agents ? JSON.stringify(input.agents) : null,
|
|
3542
|
+
input.integrationTools ? JSON.stringify(input.integrationTools) : null,
|
|
3543
|
+
input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
|
|
3544
|
+
input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
|
|
3545
|
+
input.memory ? JSON.stringify(input.memory) : null,
|
|
3546
|
+
input.scorers ? JSON.stringify(input.scorers) : null,
|
|
3474
3547
|
input.changedFields ? JSON.stringify(input.changedFields) : null,
|
|
3475
3548
|
input.changeMessage ?? null,
|
|
3476
3549
|
nowIso,
|
|
@@ -3675,7 +3748,18 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3675
3748
|
agentId: row.agentId,
|
|
3676
3749
|
versionNumber: row.versionNumber,
|
|
3677
3750
|
name: row.name,
|
|
3678
|
-
|
|
3751
|
+
description: row.description,
|
|
3752
|
+
instructions: row.instructions,
|
|
3753
|
+
model: this.parseJson(row.model, "model"),
|
|
3754
|
+
tools: this.parseJson(row.tools, "tools"),
|
|
3755
|
+
defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
|
|
3756
|
+
workflows: this.parseJson(row.workflows, "workflows"),
|
|
3757
|
+
agents: this.parseJson(row.agents, "agents"),
|
|
3758
|
+
integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
|
|
3759
|
+
inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
|
|
3760
|
+
outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
|
|
3761
|
+
memory: this.parseJson(row.memory, "memory"),
|
|
3762
|
+
scorers: this.parseJson(row.scorers, "scorers"),
|
|
3679
3763
|
changedFields: this.parseJson(row.changedFields, "changedFields"),
|
|
3680
3764
|
changeMessage: row.changeMessage,
|
|
3681
3765
|
createdAt: row.createdAtZ || row.createdAt
|