@lumifai/harness-tool-pack-postgres 0.0.1 → 0.1.0
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/README.md +24 -8
- package/dist/catalog.d.ts +6 -0
- package/dist/catalog.js +23 -0
- package/dist/catalog.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/pg-client.d.ts +19 -0
- package/dist/pg-client.js +66 -0
- package/dist/pg-client.js.map +1 -0
- package/dist/postgres-write.d.ts +41 -0
- package/dist/postgres-write.js +391 -0
- package/dist/postgres-write.js.map +1 -0
- package/dist/postgres.d.ts +29 -6
- package/dist/postgres.js +185 -35
- package/dist/postgres.js.map +1 -1
- package/dist/query-executor.js +26 -1
- package/dist/query-executor.js.map +1 -1
- package/dist/query-language.js +11 -4
- package/dist/query-language.js.map +1 -1
- package/package.json +8 -3
- package/skills/postgres-write/SKILL.md +81 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MAX_POSTGRES_PARAMETERS = exports.DEFAULT_POSTGRES_WRITE_MAX_ROWS = void 0;
|
|
7
|
+
exports.resolvePostgresWriteSkillPath = resolvePostgresWriteSkillPath;
|
|
8
|
+
exports.createPostgresWriteTools = createPostgresWriteTools;
|
|
9
|
+
exports.validatePostgresWriteOptions = validatePostgresWriteOptions;
|
|
10
|
+
exports.assertWorkspaceRelativePath = assertWorkspaceRelativePath;
|
|
11
|
+
exports.valuePlaceholder = valuePlaceholder;
|
|
12
|
+
exports.insertRows = insertRows;
|
|
13
|
+
exports.updateRow = updateRow;
|
|
14
|
+
const tools_1 = require("@mastra/core/tools");
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const zod_1 = require("zod");
|
|
17
|
+
const pg_client_1 = require("./pg-client");
|
|
18
|
+
exports.DEFAULT_POSTGRES_WRITE_MAX_ROWS = 500;
|
|
19
|
+
exports.MAX_POSTGRES_PARAMETERS = 65_535;
|
|
20
|
+
/** A safe SQL identifier — used to validate schema/table/column names we must inline (pg cannot parameterize identifiers). */
|
|
21
|
+
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
22
|
+
const workspaceFilePathSchema = zod_1.z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.describe('Workspace-relative path to a JSON file, e.g. campaigns/123/brief.json');
|
|
26
|
+
const identifierSchema = (label) => zod_1.z
|
|
27
|
+
.string()
|
|
28
|
+
.min(1)
|
|
29
|
+
.regex(IDENTIFIER, `${label} must be a valid SQL identifier ([A-Za-z_][A-Za-z0-9_]*)`);
|
|
30
|
+
const tableTargetSchema = zod_1.z.object({
|
|
31
|
+
schema: identifierSchema('schema').default('public'),
|
|
32
|
+
table: identifierSchema('table'),
|
|
33
|
+
});
|
|
34
|
+
const whereValueSchema = zod_1.z.union([zod_1.z.string().min(1), zod_1.z.number(), zod_1.z.boolean()]);
|
|
35
|
+
function resolvePostgresWriteSkillPath() {
|
|
36
|
+
const packageRoot = path_1.default.dirname(require.resolve('@lumifai/harness-tool-pack-postgres/package.json'));
|
|
37
|
+
return path_1.default.join(packageRoot, 'skills', 'postgres-write');
|
|
38
|
+
}
|
|
39
|
+
function createPostgresWriteTools(options) {
|
|
40
|
+
const maxRows = options.maxRows ?? exports.DEFAULT_POSTGRES_WRITE_MAX_ROWS;
|
|
41
|
+
const postgresInsertFromFile = (0, tools_1.createTool)({
|
|
42
|
+
id: 'postgres_insert_from_file',
|
|
43
|
+
description: 'Deterministically read a JSON file from the workspace and insert its rows into a PostgreSQL table. ' +
|
|
44
|
+
'The file must contain a JSON object or an array of objects with identical keys per row. ' +
|
|
45
|
+
'Object/array values are stored as JSON (suitable for json/jsonb columns). ' +
|
|
46
|
+
'Use conflictColumns + onConflict for idempotent saves (ignore or upsert). ' +
|
|
47
|
+
'Does NOT run arbitrary SQL.',
|
|
48
|
+
inputSchema: zod_1.z.object({
|
|
49
|
+
path: workspaceFilePathSchema,
|
|
50
|
+
...tableTargetSchema.shape,
|
|
51
|
+
conflictColumns: zod_1.z
|
|
52
|
+
.array(identifierSchema('conflictColumns'))
|
|
53
|
+
.optional()
|
|
54
|
+
.describe('Columns forming a unique/PK constraint. Required when onConflict is set.'),
|
|
55
|
+
onConflict: zod_1.z
|
|
56
|
+
.enum(['ignore', 'update'])
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('When conflictColumns are set: ignore = DO NOTHING; update = DO UPDATE SET non-key columns from EXCLUDED.'),
|
|
59
|
+
}),
|
|
60
|
+
execute: async (inputData, context) => {
|
|
61
|
+
const target = tableTargetKey(inputData.schema, inputData.table);
|
|
62
|
+
assertAllowedTable(options, inputData.schema, inputData.table);
|
|
63
|
+
const rows = await readJsonRows(context, inputData.path);
|
|
64
|
+
assertNonEmptyInsertRows(rows, inputData.path);
|
|
65
|
+
assertMaxRows(rows.length, maxRows);
|
|
66
|
+
const columns = unionColumns(rows);
|
|
67
|
+
if (columns.length === 0) {
|
|
68
|
+
throw new Error('No columns found: each row must be a non-empty JSON object.');
|
|
69
|
+
}
|
|
70
|
+
assertUniformRowKeys(rows, inputData.path);
|
|
71
|
+
assertAllowedColumns(options, target, columns);
|
|
72
|
+
assertConflictColumns(columns, inputData.conflictColumns);
|
|
73
|
+
const onConflict = resolveOnConflictMode(inputData.onConflict, inputData.conflictColumns);
|
|
74
|
+
return (0, pg_client_1.withPostgresClient)(options, context, async (client) => {
|
|
75
|
+
return (0, pg_client_1.withPostgresTransaction)(client, options, async () => {
|
|
76
|
+
const affected = await insertRows(client, inputData.schema, inputData.table, columns, rows, inputData.conflictColumns, onConflict, jsonColumnSet(options, target));
|
|
77
|
+
return {
|
|
78
|
+
table: target,
|
|
79
|
+
columns,
|
|
80
|
+
rowCount: rows.length,
|
|
81
|
+
affected,
|
|
82
|
+
onConflict,
|
|
83
|
+
skipped: onConflict === 'ignore' && inputData.conflictColumns?.length
|
|
84
|
+
? rows.length - affected
|
|
85
|
+
: 0,
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
const postgresUpdateFromFile = (0, tools_1.createTool)({
|
|
92
|
+
id: 'postgres_update_from_file',
|
|
93
|
+
description: 'Deterministically read column values from a workspace JSON file and update one PostgreSQL row. ' +
|
|
94
|
+
'The file must be a flat JSON object whose keys are column names and values are the new data. ' +
|
|
95
|
+
'Lookup is provided via whereColumn + whereValue tool args, or resolveWhereValue at boot. ' +
|
|
96
|
+
'Does NOT run arbitrary SQL.',
|
|
97
|
+
inputSchema: zod_1.z.object({
|
|
98
|
+
path: workspaceFilePathSchema.describe('Workspace-relative path to a JSON file containing only the column values to update.'),
|
|
99
|
+
...tableTargetSchema.shape,
|
|
100
|
+
whereColumn: identifierSchema('whereColumn')
|
|
101
|
+
.default('id')
|
|
102
|
+
.describe('Column used to find the row (e.g. id, campaign_id). Defaults to id.'),
|
|
103
|
+
whereValue: whereValueSchema
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('Value to match in whereColumn. Omit when resolveWhereValue is configured at boot.'),
|
|
106
|
+
}),
|
|
107
|
+
execute: async (inputData, context) => {
|
|
108
|
+
const target = tableTargetKey(inputData.schema, inputData.table);
|
|
109
|
+
assertAllowedTable(options, inputData.schema, inputData.table);
|
|
110
|
+
const whereValue = await resolveUpdateWhereValue(options, context, inputData.whereValue);
|
|
111
|
+
const set = await readUpdateColumnsFromFile(context, inputData.path, inputData.whereColumn);
|
|
112
|
+
const columns = Object.keys(set);
|
|
113
|
+
assertAllowedColumns(options, target, columns);
|
|
114
|
+
return (0, pg_client_1.withPostgresClient)(options, context, async (client) => {
|
|
115
|
+
return (0, pg_client_1.withPostgresTransaction)(client, options, async () => {
|
|
116
|
+
const rowCount = await updateRow(client, inputData.schema, inputData.table, inputData.whereColumn, whereValue, columns, set, jsonColumnSet(options, target));
|
|
117
|
+
assertExactlyOneRowUpdated(rowCount, inputData.whereColumn, whereValue);
|
|
118
|
+
return {
|
|
119
|
+
table: target,
|
|
120
|
+
whereColumn: inputData.whereColumn,
|
|
121
|
+
whereValue,
|
|
122
|
+
columns,
|
|
123
|
+
updated: true,
|
|
124
|
+
rowCount,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
postgres_insert_from_file: postgresInsertFromFile,
|
|
132
|
+
postgres_update_from_file: postgresUpdateFromFile,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function validatePostgresWriteOptions(options) {
|
|
136
|
+
if (!options.allowedTables?.length) {
|
|
137
|
+
throw new Error('Postgres file-write tools require allowedTables with at least one schema.table entry.');
|
|
138
|
+
}
|
|
139
|
+
const allowedTableSet = new Set(options.allowedTables);
|
|
140
|
+
for (const key of Object.keys(options.allowedColumns ?? {})) {
|
|
141
|
+
if (!allowedTableSet.has(key)) {
|
|
142
|
+
throw new Error(`allowedColumns key "${key}" is not listed in allowedTables.`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
for (const key of Object.keys(options.jsonColumns ?? {})) {
|
|
146
|
+
if (!allowedTableSet.has(key)) {
|
|
147
|
+
throw new Error(`jsonColumns key "${key}" is not listed in allowedTables.`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const target of options.allowedTables) {
|
|
151
|
+
const columns = options.allowedColumns?.[target];
|
|
152
|
+
if (!columns?.length) {
|
|
153
|
+
throw new Error(`allowedColumns must list at least one writable column for ${target}.`);
|
|
154
|
+
}
|
|
155
|
+
for (const column of columns) {
|
|
156
|
+
assertIdentifier(column, `allowedColumns column for ${target}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function tableTargetKey(schema, table) {
|
|
161
|
+
return `${schema}.${table}`;
|
|
162
|
+
}
|
|
163
|
+
function jsonColumnSet(options, target) {
|
|
164
|
+
return new Set(options.jsonColumns?.[target] ?? []);
|
|
165
|
+
}
|
|
166
|
+
function assertAllowedTable(options, schema, table) {
|
|
167
|
+
if (!options.allowedTables.length) {
|
|
168
|
+
throw new Error('Postgres write tools require allowedTables to be configured with at least one schema.table target.');
|
|
169
|
+
}
|
|
170
|
+
const target = tableTargetKey(schema, table);
|
|
171
|
+
if (!options.allowedTables.includes(target)) {
|
|
172
|
+
throw new Error(`Writing to ${target} is not allowed. Allowed targets: ${options.allowedTables.join(', ')}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function assertAllowedColumns(options, target, columns) {
|
|
176
|
+
const allowed = options.allowedColumns?.[target];
|
|
177
|
+
if (!allowed?.length) {
|
|
178
|
+
throw new Error(`No writable columns are configured for ${target}.`);
|
|
179
|
+
}
|
|
180
|
+
const allowedSet = new Set(allowed);
|
|
181
|
+
for (const column of columns) {
|
|
182
|
+
if (!allowedSet.has(column)) {
|
|
183
|
+
throw new Error(`Column "${column}" is not allowed on ${target}. Allowed columns: ${allowed.join(', ')}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function assertConflictColumns(columns, conflictColumns) {
|
|
188
|
+
if (!conflictColumns?.length) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const columnSet = new Set(columns);
|
|
192
|
+
for (const column of conflictColumns) {
|
|
193
|
+
if (!columnSet.has(column)) {
|
|
194
|
+
throw new Error(`conflictColumns includes "${column}" which is not present in the inserted data columns: ${columns.join(', ')}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function resolveOnConflictMode(onConflict, conflictColumns) {
|
|
199
|
+
if (!onConflict) {
|
|
200
|
+
return conflictColumns?.length ? 'ignore' : undefined;
|
|
201
|
+
}
|
|
202
|
+
if (!conflictColumns?.length) {
|
|
203
|
+
throw new Error('onConflict requires conflictColumns to be set.');
|
|
204
|
+
}
|
|
205
|
+
return onConflict;
|
|
206
|
+
}
|
|
207
|
+
function assertMaxRows(rowCount, maxRows) {
|
|
208
|
+
if (rowCount > maxRows) {
|
|
209
|
+
throw new Error(`Insert file contains ${rowCount} rows which exceeds the configured maxRows limit of ${maxRows}.`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function assertNonEmptyInsertRows(rows, path) {
|
|
213
|
+
if (rows.length === 0) {
|
|
214
|
+
throw new Error(`Insert file at ${path} must contain at least one JSON object.`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function assertUniformRowKeys(rows, path) {
|
|
218
|
+
const expectedKeys = Object.keys(rows[0] ?? {})
|
|
219
|
+
.sort()
|
|
220
|
+
.join(',');
|
|
221
|
+
for (let index = 1; index < rows.length; index++) {
|
|
222
|
+
const keys = Object.keys(rows[index] ?? {})
|
|
223
|
+
.sort()
|
|
224
|
+
.join(',');
|
|
225
|
+
if (keys !== expectedKeys) {
|
|
226
|
+
throw new Error(`Insert file at ${path}: row ${index} has columns [${keys}] but row 0 has [${expectedKeys}]. All rows must share the same keys.`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function assertExactlyOneRowUpdated(rowCount, whereColumn, whereValue) {
|
|
231
|
+
if (rowCount === 0) {
|
|
232
|
+
throw new Error(`No row found where ${whereColumn} = ${JSON.stringify(whereValue)}.`);
|
|
233
|
+
}
|
|
234
|
+
if (rowCount > 1) {
|
|
235
|
+
throw new Error(`Expected exactly one row to update where ${whereColumn} = ${JSON.stringify(whereValue)}, but matched ${rowCount}.`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async function resolveUpdateWhereValue(options, context, whereValue) {
|
|
239
|
+
if (whereValue !== undefined) {
|
|
240
|
+
return whereValue;
|
|
241
|
+
}
|
|
242
|
+
if (options.resolveWhereValue) {
|
|
243
|
+
const resolved = await options.resolveWhereValue(context);
|
|
244
|
+
if (resolved !== undefined) {
|
|
245
|
+
return resolved;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
throw new Error('postgres_update_from_file requires whereValue in tool args or resolveWhereValue at pack boot.');
|
|
249
|
+
}
|
|
250
|
+
async function readJsonRows(context, path) {
|
|
251
|
+
const parsed = await readWorkspaceJson(context, path);
|
|
252
|
+
if (Array.isArray(parsed) && parsed.length === 0) {
|
|
253
|
+
throw new Error(`Insert file at ${path} must contain at least one JSON object.`);
|
|
254
|
+
}
|
|
255
|
+
const rows = Array.isArray(parsed) ? parsed : [parsed];
|
|
256
|
+
return rows.map((row, index) => {
|
|
257
|
+
if (!row || typeof row !== 'object' || Array.isArray(row)) {
|
|
258
|
+
throw new Error(`Row ${index} at ${path} is not a JSON object.`);
|
|
259
|
+
}
|
|
260
|
+
return row;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async function readUpdateColumnsFromFile(context, path, whereColumn) {
|
|
264
|
+
const parsed = await readWorkspaceJson(context, path);
|
|
265
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
266
|
+
throw new Error(`Update file at ${path} must be a JSON object of column values.`);
|
|
267
|
+
}
|
|
268
|
+
const set = parsed;
|
|
269
|
+
const columns = Object.keys(set);
|
|
270
|
+
if (columns.length === 0) {
|
|
271
|
+
throw new Error(`Update file at ${path} must contain at least one column to update.`);
|
|
272
|
+
}
|
|
273
|
+
for (const column of columns) {
|
|
274
|
+
assertIdentifier(column, 'column');
|
|
275
|
+
if (column === whereColumn) {
|
|
276
|
+
throw new Error(`Update file at ${path}: cannot update lookup column "${whereColumn}". ` +
|
|
277
|
+
'Pass whereColumn/whereValue as tool args instead.');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return set;
|
|
281
|
+
}
|
|
282
|
+
async function readWorkspaceJson(context, path) {
|
|
283
|
+
const workspace = context.workspace;
|
|
284
|
+
if (!workspace?.filesystem?.readFile) {
|
|
285
|
+
throw new Error(`Postgres write tools require a workspace filesystem to read ${path}`);
|
|
286
|
+
}
|
|
287
|
+
assertWorkspaceRelativePath(path);
|
|
288
|
+
const fileContent = await workspace.filesystem.readFile(path, { encoding: 'utf8' });
|
|
289
|
+
const content = typeof fileContent === 'string' ? fileContent : fileContent.toString('utf8');
|
|
290
|
+
try {
|
|
291
|
+
return JSON.parse(content);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
throw new Error(`Failed to parse JSON at ${path}`, { cause: error });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function assertWorkspaceRelativePath(filePath) {
|
|
298
|
+
const normalized = filePath.replaceAll('\\', '/');
|
|
299
|
+
const segments = normalized.split('/');
|
|
300
|
+
if (normalized.startsWith('/') ||
|
|
301
|
+
/^[A-Za-z]:\//.test(normalized) ||
|
|
302
|
+
normalized.startsWith('//') ||
|
|
303
|
+
normalized.includes('\0') ||
|
|
304
|
+
segments.includes('..')) {
|
|
305
|
+
throw new Error(`Workspace path must remain within the workspace: ${filePath}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function assertIdentifier(value, label) {
|
|
309
|
+
if (!IDENTIFIER.test(value)) {
|
|
310
|
+
throw new Error(`${label} "${value}" is not a valid SQL identifier.`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function unionColumns(rows) {
|
|
314
|
+
const columns = new Set();
|
|
315
|
+
for (const row of rows) {
|
|
316
|
+
for (const key of Object.keys(row)) {
|
|
317
|
+
assertIdentifier(key, 'column');
|
|
318
|
+
columns.add(key);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return [...columns];
|
|
322
|
+
}
|
|
323
|
+
function valuePlaceholder(column, placeholderIndex, jsonColumns) {
|
|
324
|
+
const placeholder = `$${placeholderIndex}`;
|
|
325
|
+
return jsonColumns.has(column) ? `${placeholder}::jsonb` : placeholder;
|
|
326
|
+
}
|
|
327
|
+
async function insertRows(client, schema, table, columns, rows, conflictColumns, onConflict, jsonColumns) {
|
|
328
|
+
const quotedTable = `"${schema}"."${table}"`;
|
|
329
|
+
const quotedColumns = columns.map((column) => `"${column}"`).join(', ');
|
|
330
|
+
if (columns.length === 0)
|
|
331
|
+
return 0;
|
|
332
|
+
if (columns.length > exports.MAX_POSTGRES_PARAMETERS) {
|
|
333
|
+
throw new Error(`Insert has ${columns.length} columns, exceeding PostgreSQL's ${exports.MAX_POSTGRES_PARAMETERS} parameter limit per row.`);
|
|
334
|
+
}
|
|
335
|
+
const rowsPerBatch = Math.floor(exports.MAX_POSTGRES_PARAMETERS / columns.length);
|
|
336
|
+
let affected = 0;
|
|
337
|
+
for (let start = 0; start < rows.length; start += rowsPerBatch) {
|
|
338
|
+
const batch = rows.slice(start, start + rowsPerBatch);
|
|
339
|
+
const values = [];
|
|
340
|
+
const tuples = [];
|
|
341
|
+
let placeholder = 1;
|
|
342
|
+
for (const row of batch) {
|
|
343
|
+
const rowPlaceholders = columns.map((column) => {
|
|
344
|
+
values.push(toDbValue(row[column]));
|
|
345
|
+
return valuePlaceholder(column, placeholder++, jsonColumns);
|
|
346
|
+
});
|
|
347
|
+
tuples.push(`(${rowPlaceholders.join(', ')})`);
|
|
348
|
+
}
|
|
349
|
+
let sql = `INSERT INTO ${quotedTable} (${quotedColumns}) VALUES ${tuples.join(', ')}`;
|
|
350
|
+
if (conflictColumns?.length && onConflict) {
|
|
351
|
+
const conflictTarget = conflictColumns.map((column) => `"${column}"`).join(', ');
|
|
352
|
+
if (onConflict === 'ignore') {
|
|
353
|
+
sql += ` ON CONFLICT (${conflictTarget}) DO NOTHING`;
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
const conflictSet = new Set(conflictColumns);
|
|
357
|
+
const updateColumns = columns.filter((column) => !conflictSet.has(column));
|
|
358
|
+
if (updateColumns.length === 0) {
|
|
359
|
+
throw new Error('onConflict "update" requires at least one non-conflict column in the insert data.');
|
|
360
|
+
}
|
|
361
|
+
const setClause = updateColumns
|
|
362
|
+
.map((column) => `"${column}" = EXCLUDED."${column}"`)
|
|
363
|
+
.join(', ');
|
|
364
|
+
sql += ` ON CONFLICT (${conflictTarget}) DO UPDATE SET ${setClause}`;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const result = await client.query(sql, values);
|
|
368
|
+
affected += result.rowCount ?? 0;
|
|
369
|
+
}
|
|
370
|
+
return affected;
|
|
371
|
+
}
|
|
372
|
+
async function updateRow(client, schema, table, whereColumn, whereValue, columns, set, jsonColumns) {
|
|
373
|
+
const quotedTable = `"${schema}"."${table}"`;
|
|
374
|
+
const setClause = columns
|
|
375
|
+
.map((column, index) => `"${column}" = ${valuePlaceholder(column, index + 1, jsonColumns)}`)
|
|
376
|
+
.join(', ');
|
|
377
|
+
const wherePlaceholder = columns.length + 1;
|
|
378
|
+
const sql = `UPDATE ${quotedTable} SET ${setClause} WHERE "${whereColumn}" = $${wherePlaceholder}`;
|
|
379
|
+
const values = [...columns.map((column) => toDbValue(set[column])), toDbValue(whereValue)];
|
|
380
|
+
const result = await client.query(sql, values);
|
|
381
|
+
return result.rowCount ?? 0;
|
|
382
|
+
}
|
|
383
|
+
/** Primitives pass through; objects/arrays are JSON-encoded for json/jsonb columns. */
|
|
384
|
+
function toDbValue(value) {
|
|
385
|
+
if (value === null || value === undefined)
|
|
386
|
+
return null;
|
|
387
|
+
if (typeof value === 'object')
|
|
388
|
+
return JSON.stringify(value);
|
|
389
|
+
return value;
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=postgres-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-write.js","sourceRoot":"","sources":["../src/postgres-write.ts"],"names":[],"mappings":"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"}
|
package/dist/postgres.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { ToolsInput } from '@mastra/core/agent';
|
|
2
2
|
import { type ToolExecutionContext } from '@mastra/core/tools';
|
|
3
|
+
import { type PostgresCatalog } from './catalog';
|
|
3
4
|
import { type InsertAuditCallback } from './insert-executor';
|
|
4
5
|
import { insertInputSchema, insertResultSchema } from './insert-language';
|
|
5
6
|
import { previewInputSchema, queryPlanSchema, schemaDetailsInputSchema } from './query-language';
|
|
7
|
+
import { type PostgresClientOptions } from './pg-client';
|
|
6
8
|
import { type AuditCallback } from './query-executor';
|
|
7
9
|
export { DEFAULT_POSTGRES_QUERY_LIMIT, MAX_POSTGRES_QUERY_LIMIT, DEFAULT_MAX_INSERT_ROWS, MAX_INSERT_ROWS, } from './constants';
|
|
8
10
|
export type { QueryPlan, QueryResult } from './query-language';
|
|
9
11
|
export type { InsertInput, InsertResult } from './insert-language';
|
|
10
12
|
export { queryPlanSchema, previewInputSchema, schemaDetailsInputSchema, insertInputSchema, insertResultSchema, };
|
|
11
13
|
type MaybePromise<T> = T | Promise<T>;
|
|
12
|
-
export interface PostgresToolsOptions {
|
|
13
|
-
connectionString?: string;
|
|
14
|
-
resolveConnectionString?: (context: ToolExecutionContext) => MaybePromise<string>;
|
|
14
|
+
export interface PostgresToolsOptions extends PostgresClientOptions {
|
|
15
15
|
defaultQueryLimit?: number;
|
|
16
16
|
maxQueryLimit?: number;
|
|
17
17
|
defaultPreviewLimit?: number;
|
|
@@ -19,9 +19,6 @@ export interface PostgresToolsOptions {
|
|
|
19
19
|
maxInsertRows?: number;
|
|
20
20
|
maxInsertCsvBytes?: number;
|
|
21
21
|
maxInsertRejectionDetails?: number;
|
|
22
|
-
statementTimeoutMs?: number;
|
|
23
|
-
lockTimeoutMs?: number;
|
|
24
|
-
idleInTransactionTimeoutMs?: number;
|
|
25
22
|
tempFileLimitKb?: number;
|
|
26
23
|
searchPath?: string[];
|
|
27
24
|
maxResultBytes?: number;
|
|
@@ -33,7 +30,33 @@ export interface PostgresToolsOptions {
|
|
|
33
30
|
catalogCacheTtlMs?: number;
|
|
34
31
|
audit?: AuditCallback;
|
|
35
32
|
insertAudit?: InsertAuditCallback;
|
|
33
|
+
/**
|
|
34
|
+
* Optional `schema.table` allowlist for postgres_query / postgres_preview_data /
|
|
35
|
+
* postgres_insert. When set, the loaded catalog is intersected with this list so
|
|
36
|
+
* deployments can restrict access beyond DB role grants. Independent of
|
|
37
|
+
* `allowedTables` (file-write tools).
|
|
38
|
+
*/
|
|
39
|
+
allowedPhysicalTables?: string[];
|
|
40
|
+
/** Fully-qualified `schema.table` targets for the file-based write tools. */
|
|
41
|
+
allowedTables?: string[];
|
|
42
|
+
/** Per-table column allowlist required by the file-based write tools. */
|
|
43
|
+
allowedColumns?: Record<string, string[]>;
|
|
44
|
+
/** Per-table JSON/JSONB columns for the file-based write tools. */
|
|
45
|
+
jsonColumns?: Record<string, string[]>;
|
|
46
|
+
/** Maximum rows read from one file by the file-based write tools. */
|
|
47
|
+
maxRows?: number;
|
|
48
|
+
/** Resolve update lookup values when the tool omits `whereValue`. */
|
|
49
|
+
resolveWhereValue?: (context: ToolExecutionContext) => MaybePromise<string | number | boolean | undefined>;
|
|
36
50
|
}
|
|
37
51
|
export declare function resolvePostgresSkillPath(): string;
|
|
38
52
|
export declare function createPostgresTools(options: PostgresToolsOptions): ToolsInput;
|
|
39
53
|
export declare function createPostgresToolPack(options: PostgresToolsOptions): import("@lumifai/harness-tool-packs").ToolPack;
|
|
54
|
+
/**
|
|
55
|
+
* Intersect the catalog with the optional physical-table allowlist.
|
|
56
|
+
* When `primary` is provided, reject that target with POLICY_DENIED if it is
|
|
57
|
+
* outside the allowlist (clearer than UNKNOWN_RELATION after filtering).
|
|
58
|
+
*/
|
|
59
|
+
export declare function applyPhysicalTableAllowlist(catalog: PostgresCatalog, allowlist: Set<string> | undefined, primary?: {
|
|
60
|
+
schema: string;
|
|
61
|
+
relation: string;
|
|
62
|
+
}): PostgresCatalog;
|