@agentforge/tools 0.16.40 → 0.16.42

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.cjs CHANGED
@@ -6061,156 +6061,7 @@ async function withTransaction(manager, operation, options) {
6061
6061
  // src/data/relational/schema/validation.ts
6062
6062
  var VALID_TABLE_FILTER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)?$/;
6063
6063
 
6064
- // src/data/relational/schema/schema-inspector.ts
6065
- var logger13 = core.createLogger("agentforge:tools:data:relational:schema-inspector");
6066
- var DEFAULT_CACHE_TTL_MS = 6e4;
6067
- var schemaCache = /* @__PURE__ */ new Map();
6068
- var POSTGRES_TABLES_QUERY = `
6069
- SELECT
6070
- table_schema AS schema_name,
6071
- table_name
6072
- FROM information_schema.tables
6073
- WHERE table_type = 'BASE TABLE'
6074
- AND table_schema NOT IN ('pg_catalog', 'information_schema')
6075
- ORDER BY table_schema, table_name
6076
- `;
6077
- var POSTGRES_COLUMNS_QUERY = `
6078
- SELECT
6079
- table_schema AS schema_name,
6080
- table_name,
6081
- column_name,
6082
- data_type,
6083
- is_nullable,
6084
- column_default
6085
- FROM information_schema.columns
6086
- WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
6087
- ORDER BY table_schema, table_name, ordinal_position
6088
- `;
6089
- var POSTGRES_PRIMARY_KEYS_QUERY = `
6090
- SELECT
6091
- kcu.table_schema AS schema_name,
6092
- kcu.table_name,
6093
- kcu.column_name,
6094
- kcu.ordinal_position AS key_position
6095
- FROM information_schema.table_constraints tc
6096
- JOIN information_schema.key_column_usage kcu
6097
- ON tc.constraint_name = kcu.constraint_name
6098
- AND tc.table_schema = kcu.table_schema
6099
- AND tc.table_name = kcu.table_name
6100
- WHERE tc.constraint_type = 'PRIMARY KEY'
6101
- ORDER BY kcu.table_schema, kcu.table_name, kcu.ordinal_position
6102
- `;
6103
- var POSTGRES_FOREIGN_KEYS_QUERY = `
6104
- SELECT
6105
- tc.table_schema AS schema_name,
6106
- tc.table_name,
6107
- tc.constraint_name,
6108
- kcu.column_name,
6109
- ccu.table_schema AS referenced_schema_name,
6110
- ccu.table_name AS referenced_table_name,
6111
- ccu.column_name AS referenced_column_name
6112
- FROM information_schema.table_constraints tc
6113
- JOIN information_schema.key_column_usage kcu
6114
- ON tc.constraint_name = kcu.constraint_name
6115
- AND tc.table_schema = kcu.table_schema
6116
- JOIN information_schema.constraint_column_usage ccu
6117
- ON ccu.constraint_name = tc.constraint_name
6118
- AND ccu.table_schema = tc.table_schema
6119
- WHERE tc.constraint_type = 'FOREIGN KEY'
6120
- ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position
6121
- `;
6122
- var POSTGRES_INDEXES_QUERY = `
6123
- SELECT
6124
- ns.nspname AS schema_name,
6125
- tbl.relname AS table_name,
6126
- idx.relname AS index_name,
6127
- ix.indisunique AS is_unique,
6128
- att.attname AS column_name,
6129
- ord.ordinality AS column_position
6130
- FROM pg_class tbl
6131
- JOIN pg_namespace ns
6132
- ON ns.oid = tbl.relnamespace
6133
- JOIN pg_index ix
6134
- ON ix.indrelid = tbl.oid
6135
- JOIN pg_class idx
6136
- ON idx.oid = ix.indexrelid
6137
- JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS ord(attnum, ordinality)
6138
- ON true
6139
- JOIN pg_attribute att
6140
- ON att.attrelid = tbl.oid
6141
- AND att.attnum = ord.attnum
6142
- WHERE tbl.relkind = 'r'
6143
- AND ns.nspname NOT IN ('pg_catalog', 'information_schema')
6144
- AND ix.indisprimary = false
6145
- ORDER BY ns.nspname, tbl.relname, idx.relname, ord.ordinality
6146
- `;
6147
- var MYSQL_TABLES_QUERY = `
6148
- SELECT
6149
- table_schema AS schema_name,
6150
- table_name AS table_name
6151
- FROM information_schema.tables
6152
- WHERE table_type = 'BASE TABLE'
6153
- AND table_schema = DATABASE()
6154
- ORDER BY table_name
6155
- `;
6156
- var MYSQL_COLUMNS_QUERY = `
6157
- SELECT
6158
- table_schema AS schema_name,
6159
- table_name AS table_name,
6160
- column_name AS column_name,
6161
- column_type AS data_type,
6162
- is_nullable AS is_nullable,
6163
- column_default AS column_default
6164
- FROM information_schema.columns
6165
- WHERE table_schema = DATABASE()
6166
- ORDER BY table_name, ordinal_position
6167
- `;
6168
- var MYSQL_PRIMARY_KEYS_QUERY = `
6169
- SELECT
6170
- table_schema AS schema_name,
6171
- table_name AS table_name,
6172
- column_name AS column_name,
6173
- ordinal_position AS key_position
6174
- FROM information_schema.key_column_usage
6175
- WHERE table_schema = DATABASE()
6176
- AND constraint_name = 'PRIMARY'
6177
- ORDER BY table_name, ordinal_position
6178
- `;
6179
- var MYSQL_FOREIGN_KEYS_QUERY = `
6180
- SELECT
6181
- table_schema AS schema_name,
6182
- table_name AS table_name,
6183
- constraint_name AS constraint_name,
6184
- column_name AS column_name,
6185
- referenced_table_schema AS referenced_schema_name,
6186
- referenced_table_name AS referenced_table_name,
6187
- referenced_column_name AS referenced_column_name
6188
- FROM information_schema.key_column_usage
6189
- WHERE table_schema = DATABASE()
6190
- AND referenced_table_name IS NOT NULL
6191
- ORDER BY table_name, constraint_name, ordinal_position
6192
- `;
6193
- var MYSQL_INDEXES_QUERY = `
6194
- SELECT
6195
- table_schema AS schema_name,
6196
- table_name AS table_name,
6197
- index_name AS index_name,
6198
- non_unique AS non_unique,
6199
- column_name AS column_name,
6200
- seq_in_index AS seq_in_index
6201
- FROM information_schema.statistics
6202
- WHERE table_schema = DATABASE()
6203
- AND index_name <> 'PRIMARY'
6204
- ORDER BY table_name, index_name, seq_in_index
6205
- `;
6206
- var SQLITE_TABLES_QUERY = `
6207
- SELECT
6208
- name AS table_name
6209
- FROM sqlite_master
6210
- WHERE type = 'table'
6211
- AND name NOT LIKE 'sqlite_%'
6212
- ORDER BY name
6213
- `;
6064
+ // src/data/relational/schema/schema-inspector-shared.ts
6214
6065
  function normalizeFilterName(value) {
6215
6066
  return value.trim().toLowerCase();
6216
6067
  }
@@ -6306,14 +6157,391 @@ function escapeSqliteStringLiteral(value) {
6306
6157
  function sortColumnsByPosition(columnsByPosition) {
6307
6158
  return columnsByPosition.sort((a, b) => a.position - b.position).map((entry) => entry.column);
6308
6159
  }
6160
+ function createTableMap(refs) {
6161
+ const tableMap2 = /* @__PURE__ */ new Map();
6162
+ for (const ref of refs) {
6163
+ const key = buildTableKey(ref.tableName, ref.schemaName);
6164
+ tableMap2.set(key, {
6165
+ name: ref.tableName,
6166
+ schema: ref.schemaName,
6167
+ columns: [],
6168
+ primaryKey: [],
6169
+ foreignKeys: [],
6170
+ indexes: []
6171
+ });
6172
+ }
6173
+ return tableMap2;
6174
+ }
6175
+ function getTableFromRow(tableMap2, row, tableField, schemaField) {
6176
+ const tableName = toStringValue(row[tableField]);
6177
+ const schemaName = toOptionalStringValue(row[schemaField]) ;
6178
+ const key = buildTableKey(tableName, schemaName);
6179
+ return tableMap2.get(key);
6180
+ }
6181
+ function createColumnSchema(row, fields) {
6182
+ return {
6183
+ name: toStringValue(row[fields?.name ?? "column_name"]),
6184
+ type: toStringValue(row[fields?.type ?? "data_type"]),
6185
+ isNullable: toBooleanValue(row[fields?.nullable ?? "is_nullable"]),
6186
+ defaultValue: row[fields?.defaultValue ?? "column_default"] ?? null,
6187
+ isPrimaryKey: fields?.primaryKey ?? false
6188
+ };
6189
+ }
6190
+ function applyPrimaryKeyColumn(table, columnName) {
6191
+ table.primaryKey.push(columnName);
6192
+ const column = table.columns.find((entry) => entry.name === columnName);
6193
+ if (column) {
6194
+ column.isPrimaryKey = true;
6195
+ }
6196
+ }
6197
+ function applyIndexRows(tableMap2, rows, tableField, schemaField, config) {
6198
+ const grouped = /* @__PURE__ */ new Map();
6199
+ for (const row of rows) {
6200
+ const table = getTableFromRow(tableMap2, row, tableField, schemaField);
6201
+ if (!table) {
6202
+ continue;
6203
+ }
6204
+ const indexName = toStringValue(row[config.indexNameField]);
6205
+ if (!indexName) {
6206
+ continue;
6207
+ }
6208
+ const groupKey = `${table.schema ?? ""}.${table.name}.${indexName}`;
6209
+ const entry = grouped.get(groupKey) ?? {
6210
+ table,
6211
+ indexName,
6212
+ isUnique: config.uniqueResolver(row),
6213
+ columnsByPosition: []
6214
+ };
6215
+ entry.columnsByPosition.push({
6216
+ position: toNumberValue(row[config.positionField]),
6217
+ column: toStringValue(row[config.columnField])
6218
+ });
6219
+ grouped.set(groupKey, entry);
6220
+ }
6221
+ for (const entry of grouped.values()) {
6222
+ const index = {
6223
+ name: entry.indexName,
6224
+ isUnique: entry.isUnique,
6225
+ columns: sortColumnsByPosition(entry.columnsByPosition)
6226
+ };
6227
+ entry.table.indexes.push(index);
6228
+ }
6229
+ }
6230
+
6231
+ // src/data/relational/schema/schema-inspector-mysql.ts
6232
+ var MYSQL_TABLES_QUERY = `
6233
+ SELECT
6234
+ table_schema AS schema_name,
6235
+ table_name AS table_name
6236
+ FROM information_schema.tables
6237
+ WHERE table_type = 'BASE TABLE'
6238
+ AND table_schema = DATABASE()
6239
+ ORDER BY table_name
6240
+ `;
6241
+ var MYSQL_COLUMNS_QUERY = `
6242
+ SELECT
6243
+ table_schema AS schema_name,
6244
+ table_name AS table_name,
6245
+ column_name AS column_name,
6246
+ column_type AS data_type,
6247
+ is_nullable AS is_nullable,
6248
+ column_default AS column_default
6249
+ FROM information_schema.columns
6250
+ WHERE table_schema = DATABASE()
6251
+ ORDER BY table_name, ordinal_position
6252
+ `;
6253
+ var MYSQL_PRIMARY_KEYS_QUERY = `
6254
+ SELECT
6255
+ table_schema AS schema_name,
6256
+ table_name AS table_name,
6257
+ column_name AS column_name,
6258
+ ordinal_position AS key_position
6259
+ FROM information_schema.key_column_usage
6260
+ WHERE table_schema = DATABASE()
6261
+ AND constraint_name = 'PRIMARY'
6262
+ ORDER BY table_name, ordinal_position
6263
+ `;
6264
+ var MYSQL_FOREIGN_KEYS_QUERY = `
6265
+ SELECT
6266
+ table_schema AS schema_name,
6267
+ table_name AS table_name,
6268
+ constraint_name AS constraint_name,
6269
+ column_name AS column_name,
6270
+ referenced_table_schema AS referenced_schema_name,
6271
+ referenced_table_name AS referenced_table_name,
6272
+ referenced_column_name AS referenced_column_name
6273
+ FROM information_schema.key_column_usage
6274
+ WHERE table_schema = DATABASE()
6275
+ AND referenced_table_name IS NOT NULL
6276
+ ORDER BY table_name, constraint_name, ordinal_position
6277
+ `;
6278
+ var MYSQL_INDEXES_QUERY = `
6279
+ SELECT
6280
+ table_schema AS schema_name,
6281
+ table_name AS table_name,
6282
+ index_name AS index_name,
6283
+ non_unique AS non_unique,
6284
+ column_name AS column_name,
6285
+ seq_in_index AS seq_in_index
6286
+ FROM information_schema.statistics
6287
+ WHERE table_schema = DATABASE()
6288
+ AND index_name <> 'PRIMARY'
6289
+ ORDER BY table_name, index_name, seq_in_index
6290
+ `;
6291
+ async function inspectMySQL(runQueryRows) {
6292
+ const tableRows = await runQueryRows(MYSQL_TABLES_QUERY);
6293
+ const tableMap2 = createTableMap(
6294
+ tableRows.map((row) => ({
6295
+ schemaName: toOptionalStringValue(row.schema_name),
6296
+ tableName: toStringValue(row.table_name)
6297
+ }))
6298
+ );
6299
+ const columnsRows = await runQueryRows(MYSQL_COLUMNS_QUERY);
6300
+ for (const row of columnsRows) {
6301
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6302
+ if (!table) {
6303
+ continue;
6304
+ }
6305
+ table.columns.push(createColumnSchema(row));
6306
+ }
6307
+ const primaryKeyRows = await runQueryRows(MYSQL_PRIMARY_KEYS_QUERY);
6308
+ for (const row of primaryKeyRows) {
6309
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6310
+ if (!table) {
6311
+ continue;
6312
+ }
6313
+ applyPrimaryKeyColumn(table, toStringValue(row.column_name));
6314
+ }
6315
+ const foreignKeyRows = await runQueryRows(MYSQL_FOREIGN_KEYS_QUERY);
6316
+ for (const row of foreignKeyRows) {
6317
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6318
+ if (!table) {
6319
+ continue;
6320
+ }
6321
+ const foreignKey = {
6322
+ name: toOptionalStringValue(row.constraint_name),
6323
+ column: toStringValue(row.column_name),
6324
+ referencedSchema: toOptionalStringValue(row.referenced_schema_name),
6325
+ referencedTable: toStringValue(row.referenced_table_name),
6326
+ referencedColumn: toStringValue(row.referenced_column_name)
6327
+ };
6328
+ table.foreignKeys.push(foreignKey);
6329
+ }
6330
+ const indexRows = await runQueryRows(MYSQL_INDEXES_QUERY);
6331
+ applyIndexRows(tableMap2, indexRows, "table_name", "schema_name", {
6332
+ indexNameField: "index_name",
6333
+ columnField: "column_name",
6334
+ positionField: "seq_in_index",
6335
+ uniqueResolver: (row) => !toBooleanValue(row.non_unique)
6336
+ });
6337
+ return Array.from(tableMap2.values());
6338
+ }
6339
+
6340
+ // src/data/relational/schema/schema-inspector-postgresql.ts
6341
+ var POSTGRES_TABLES_QUERY = `
6342
+ SELECT
6343
+ table_schema AS schema_name,
6344
+ table_name
6345
+ FROM information_schema.tables
6346
+ WHERE table_type = 'BASE TABLE'
6347
+ AND table_schema NOT IN ('pg_catalog', 'information_schema')
6348
+ ORDER BY table_schema, table_name
6349
+ `;
6350
+ var POSTGRES_COLUMNS_QUERY = `
6351
+ SELECT
6352
+ table_schema AS schema_name,
6353
+ table_name,
6354
+ column_name,
6355
+ data_type,
6356
+ is_nullable,
6357
+ column_default
6358
+ FROM information_schema.columns
6359
+ WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
6360
+ ORDER BY table_schema, table_name, ordinal_position
6361
+ `;
6362
+ var POSTGRES_PRIMARY_KEYS_QUERY = `
6363
+ SELECT
6364
+ kcu.table_schema AS schema_name,
6365
+ kcu.table_name,
6366
+ kcu.column_name,
6367
+ kcu.ordinal_position AS key_position
6368
+ FROM information_schema.table_constraints tc
6369
+ JOIN information_schema.key_column_usage kcu
6370
+ ON tc.constraint_name = kcu.constraint_name
6371
+ AND tc.table_schema = kcu.table_schema
6372
+ AND tc.table_name = kcu.table_name
6373
+ WHERE tc.constraint_type = 'PRIMARY KEY'
6374
+ ORDER BY kcu.table_schema, kcu.table_name, kcu.ordinal_position
6375
+ `;
6376
+ var POSTGRES_FOREIGN_KEYS_QUERY = `
6377
+ SELECT
6378
+ tc.table_schema AS schema_name,
6379
+ tc.table_name,
6380
+ tc.constraint_name,
6381
+ kcu.column_name,
6382
+ ccu.table_schema AS referenced_schema_name,
6383
+ ccu.table_name AS referenced_table_name,
6384
+ ccu.column_name AS referenced_column_name
6385
+ FROM information_schema.table_constraints tc
6386
+ JOIN information_schema.key_column_usage kcu
6387
+ ON tc.constraint_name = kcu.constraint_name
6388
+ AND tc.table_schema = kcu.table_schema
6389
+ JOIN information_schema.constraint_column_usage ccu
6390
+ ON ccu.constraint_name = tc.constraint_name
6391
+ AND ccu.table_schema = tc.table_schema
6392
+ WHERE tc.constraint_type = 'FOREIGN KEY'
6393
+ ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position
6394
+ `;
6395
+ var POSTGRES_INDEXES_QUERY = `
6396
+ SELECT
6397
+ ns.nspname AS schema_name,
6398
+ tbl.relname AS table_name,
6399
+ idx.relname AS index_name,
6400
+ ix.indisunique AS is_unique,
6401
+ att.attname AS column_name,
6402
+ ord.ordinality AS column_position
6403
+ FROM pg_class tbl
6404
+ JOIN pg_namespace ns
6405
+ ON ns.oid = tbl.relnamespace
6406
+ JOIN pg_index ix
6407
+ ON ix.indrelid = tbl.oid
6408
+ JOIN pg_class idx
6409
+ ON idx.oid = ix.indexrelid
6410
+ JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS ord(attnum, ordinality)
6411
+ ON true
6412
+ JOIN pg_attribute att
6413
+ ON att.attrelid = tbl.oid
6414
+ AND att.attnum = ord.attnum
6415
+ WHERE tbl.relkind = 'r'
6416
+ AND ns.nspname NOT IN ('pg_catalog', 'information_schema')
6417
+ AND ix.indisprimary = false
6418
+ ORDER BY ns.nspname, tbl.relname, idx.relname, ord.ordinality
6419
+ `;
6420
+ async function inspectPostgreSQL(runQueryRows) {
6421
+ const tableRows = await runQueryRows(POSTGRES_TABLES_QUERY);
6422
+ const tableMap2 = createTableMap(
6423
+ tableRows.map((row) => ({
6424
+ schemaName: toOptionalStringValue(row.schema_name),
6425
+ tableName: toStringValue(row.table_name)
6426
+ }))
6427
+ );
6428
+ const columnsRows = await runQueryRows(POSTGRES_COLUMNS_QUERY);
6429
+ for (const row of columnsRows) {
6430
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6431
+ if (!table) {
6432
+ continue;
6433
+ }
6434
+ table.columns.push(createColumnSchema(row));
6435
+ }
6436
+ const primaryKeyRows = await runQueryRows(POSTGRES_PRIMARY_KEYS_QUERY);
6437
+ for (const row of primaryKeyRows) {
6438
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6439
+ if (!table) {
6440
+ continue;
6441
+ }
6442
+ applyPrimaryKeyColumn(table, toStringValue(row.column_name));
6443
+ }
6444
+ const foreignKeyRows = await runQueryRows(POSTGRES_FOREIGN_KEYS_QUERY);
6445
+ for (const row of foreignKeyRows) {
6446
+ const table = getTableFromRow(tableMap2, row, "table_name", "schema_name");
6447
+ if (!table) {
6448
+ continue;
6449
+ }
6450
+ const foreignKey = {
6451
+ name: toOptionalStringValue(row.constraint_name),
6452
+ column: toStringValue(row.column_name),
6453
+ referencedSchema: toOptionalStringValue(row.referenced_schema_name),
6454
+ referencedTable: toStringValue(row.referenced_table_name),
6455
+ referencedColumn: toStringValue(row.referenced_column_name)
6456
+ };
6457
+ table.foreignKeys.push(foreignKey);
6458
+ }
6459
+ const indexRows = await runQueryRows(POSTGRES_INDEXES_QUERY);
6460
+ applyIndexRows(tableMap2, indexRows, "table_name", "schema_name", {
6461
+ indexNameField: "index_name",
6462
+ columnField: "column_name",
6463
+ positionField: "column_position",
6464
+ uniqueResolver: (row) => toBooleanValue(row.is_unique)
6465
+ });
6466
+ return Array.from(tableMap2.values());
6467
+ }
6468
+
6469
+ // src/data/relational/schema/schema-inspector-sqlite.ts
6470
+ var SQLITE_TABLES_QUERY = `
6471
+ SELECT
6472
+ name AS table_name
6473
+ FROM sqlite_master
6474
+ WHERE type = 'table'
6475
+ AND name NOT LIKE 'sqlite_%'
6476
+ ORDER BY name
6477
+ `;
6478
+ async function inspectSQLite(runQueryRows) {
6479
+ const tableRows = await runQueryRows(SQLITE_TABLES_QUERY);
6480
+ const tableMap2 = createTableMap(
6481
+ tableRows.map((row) => ({
6482
+ tableName: toStringValue(row.table_name)
6483
+ }))
6484
+ );
6485
+ for (const table of tableMap2.values()) {
6486
+ const tableLiteral = escapeSqliteStringLiteral(table.name);
6487
+ const columnRows = await runQueryRows(`PRAGMA table_info('${tableLiteral}')`);
6488
+ const primaryKeyColumns = [];
6489
+ for (const row of columnRows) {
6490
+ const pkPosition = toNumberValue(row.pk);
6491
+ const columnName = toStringValue(row.name);
6492
+ if (pkPosition > 0) {
6493
+ primaryKeyColumns.push({ position: pkPosition, column: columnName });
6494
+ }
6495
+ const column = createColumnSchema(row, {
6496
+ name: "name",
6497
+ type: "type",
6498
+ nullable: "notnull",
6499
+ defaultValue: "dflt_value",
6500
+ primaryKey: pkPosition > 0
6501
+ });
6502
+ column.isNullable = !toBooleanValue(row.notnull);
6503
+ table.columns.push(column);
6504
+ }
6505
+ table.primaryKey = sortColumnsByPosition(primaryKeyColumns);
6506
+ const foreignKeyRows = await runQueryRows(`PRAGMA foreign_key_list('${tableLiteral}')`);
6507
+ for (const row of foreignKeyRows) {
6508
+ const foreignKey = {
6509
+ column: toStringValue(row.from),
6510
+ referencedTable: toStringValue(row.table),
6511
+ referencedColumn: toStringValue(row.to)
6512
+ };
6513
+ table.foreignKeys.push(foreignKey);
6514
+ }
6515
+ const indexListRows = await runQueryRows(`PRAGMA index_list('${tableLiteral}')`);
6516
+ for (const indexRow of indexListRows) {
6517
+ const indexName = toStringValue(indexRow.name);
6518
+ if (!indexName || toStringValue(indexRow.origin) === "pk") {
6519
+ continue;
6520
+ }
6521
+ const indexNameLiteral = escapeSqliteStringLiteral(indexName);
6522
+ const indexInfoRows = await runQueryRows(`PRAGMA index_info('${indexNameLiteral}')`);
6523
+ const indexColumns = sortColumnsByPosition(
6524
+ indexInfoRows.map((row) => ({
6525
+ position: toNumberValue(row.seqno),
6526
+ column: toStringValue(row.name)
6527
+ }))
6528
+ );
6529
+ const index = {
6530
+ name: indexName,
6531
+ isUnique: toBooleanValue(indexRow.unique),
6532
+ columns: indexColumns
6533
+ };
6534
+ table.indexes.push(index);
6535
+ }
6536
+ }
6537
+ return Array.from(tableMap2.values());
6538
+ }
6539
+
6540
+ // src/data/relational/schema/schema-inspector.ts
6541
+ var logger13 = core.createLogger("agentforge:tools:data:relational:schema-inspector");
6542
+ var DEFAULT_CACHE_TTL_MS = 6e4;
6543
+ var schemaCache = /* @__PURE__ */ new Map();
6309
6544
  var SchemaInspector = class _SchemaInspector {
6310
- /**
6311
- * Create a new SchemaInspector.
6312
- *
6313
- * @param manager - ConnectionManager instance for database access
6314
- * @param vendor - Database vendor ('postgresql' | 'mysql' | 'sqlite')
6315
- * @param config - Optional configuration for cache TTL and cache key
6316
- */
6317
6545
  constructor(manager, vendor, config) {
6318
6546
  this.manager = manager;
6319
6547
  this.vendor = vendor;
@@ -6322,11 +6550,6 @@ var SchemaInspector = class _SchemaInspector {
6322
6550
  }
6323
6551
  cacheTtlMs;
6324
6552
  cacheKey;
6325
- /**
6326
- * Clear cached schema data.
6327
- *
6328
- * @param cacheKey - Specific cache key to clear. If omitted, clears all cached schemas.
6329
- */
6330
6553
  static clearCache(cacheKey) {
6331
6554
  if (cacheKey) {
6332
6555
  schemaCache.delete(cacheKey);
@@ -6334,18 +6557,9 @@ var SchemaInspector = class _SchemaInspector {
6334
6557
  }
6335
6558
  schemaCache.clear();
6336
6559
  }
6337
- /** Invalidate this inspector's cached schema, if any. */
6338
6560
  invalidateCache() {
6339
6561
  _SchemaInspector.clearCache(this.cacheKey);
6340
6562
  }
6341
- /**
6342
- * Inspect the database schema and return structured metadata.
6343
- *
6344
- * Results are cached when a `cacheKey` was provided at construction time.
6345
- *
6346
- * @param options - Optional table filters and cache bypass flag
6347
- * @returns Structured schema with tables, columns, indexes, and foreign keys
6348
- */
6349
6563
  async inspect(options) {
6350
6564
  const tableFilters = validateTableFilters(options?.tables);
6351
6565
  const bypassCache = options?.bypassCache ?? false;
@@ -6366,7 +6580,7 @@ var SchemaInspector = class _SchemaInspector {
6366
6580
  return filterSchemaTables(cloneSchema(schema), tableFilters);
6367
6581
  }
6368
6582
  async inspectFromDatabase() {
6369
- const tables = this.vendor === "postgresql" ? await this.inspectPostgreSQL() : this.vendor === "mysql" ? await this.inspectMySQL() : await this.inspectSQLite();
6583
+ const tables = await this.inspectTables();
6370
6584
  return {
6371
6585
  vendor: this.vendor,
6372
6586
  tables: tables.sort((left, right) => {
@@ -6377,6 +6591,18 @@ var SchemaInspector = class _SchemaInspector {
6377
6591
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
6378
6592
  };
6379
6593
  }
6594
+ async inspectTables() {
6595
+ switch (this.vendor) {
6596
+ case "postgresql":
6597
+ return inspectPostgreSQL((query) => this.runQueryRows(query));
6598
+ case "mysql":
6599
+ return inspectMySQL((query) => this.runQueryRows(query));
6600
+ case "sqlite":
6601
+ return inspectSQLite((query) => this.runQueryRows(query));
6602
+ default:
6603
+ throw new Error(`Unsupported database vendor: ${String(this.vendor)}`);
6604
+ }
6605
+ }
6380
6606
  async runQueryRows(query) {
6381
6607
  const result = await executeQuery2(this.manager, {
6382
6608
  sql: query,
@@ -6384,240 +6610,6 @@ var SchemaInspector = class _SchemaInspector {
6384
6610
  });
6385
6611
  return result.rows;
6386
6612
  }
6387
- createTableMap(refs) {
6388
- const tableMap2 = /* @__PURE__ */ new Map();
6389
- for (const ref of refs) {
6390
- const key = buildTableKey(ref.tableName, ref.schemaName);
6391
- tableMap2.set(key, {
6392
- name: ref.tableName,
6393
- schema: ref.schemaName,
6394
- columns: [],
6395
- primaryKey: [],
6396
- foreignKeys: [],
6397
- indexes: []
6398
- });
6399
- }
6400
- return tableMap2;
6401
- }
6402
- getTableFromRow(tableMap2, row, tableField, schemaField) {
6403
- const tableName = toStringValue(row[tableField]);
6404
- const schemaName = schemaField ? toOptionalStringValue(row[schemaField]) : void 0;
6405
- const key = buildTableKey(tableName, schemaName);
6406
- return tableMap2.get(key);
6407
- }
6408
- async inspectPostgreSQL() {
6409
- const tableRows = await this.runQueryRows(POSTGRES_TABLES_QUERY);
6410
- const tableMap2 = this.createTableMap(
6411
- tableRows.map((row) => ({
6412
- schemaName: toOptionalStringValue(row.schema_name),
6413
- tableName: toStringValue(row.table_name)
6414
- }))
6415
- );
6416
- const columnsRows = await this.runQueryRows(POSTGRES_COLUMNS_QUERY);
6417
- for (const row of columnsRows) {
6418
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6419
- if (!table) {
6420
- continue;
6421
- }
6422
- const column = {
6423
- name: toStringValue(row.column_name),
6424
- type: toStringValue(row.data_type),
6425
- isNullable: toBooleanValue(row.is_nullable),
6426
- defaultValue: row.column_default ?? null,
6427
- isPrimaryKey: false
6428
- };
6429
- table.columns.push(column);
6430
- }
6431
- const primaryKeyRows = await this.runQueryRows(POSTGRES_PRIMARY_KEYS_QUERY);
6432
- for (const row of primaryKeyRows) {
6433
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6434
- if (!table) {
6435
- continue;
6436
- }
6437
- const columnName = toStringValue(row.column_name);
6438
- table.primaryKey.push(columnName);
6439
- const column = table.columns.find((entry) => entry.name === columnName);
6440
- if (column) {
6441
- column.isPrimaryKey = true;
6442
- }
6443
- }
6444
- const foreignKeyRows = await this.runQueryRows(POSTGRES_FOREIGN_KEYS_QUERY);
6445
- for (const row of foreignKeyRows) {
6446
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6447
- if (!table) {
6448
- continue;
6449
- }
6450
- const foreignKey = {
6451
- name: toOptionalStringValue(row.constraint_name),
6452
- column: toStringValue(row.column_name),
6453
- referencedSchema: toOptionalStringValue(row.referenced_schema_name),
6454
- referencedTable: toStringValue(row.referenced_table_name),
6455
- referencedColumn: toStringValue(row.referenced_column_name)
6456
- };
6457
- table.foreignKeys.push(foreignKey);
6458
- }
6459
- const indexRows = await this.runQueryRows(POSTGRES_INDEXES_QUERY);
6460
- this.applyIndexRows(tableMap2, indexRows, "table_name", "schema_name", {
6461
- indexNameField: "index_name",
6462
- columnField: "column_name",
6463
- positionField: "column_position",
6464
- uniqueResolver: (row) => toBooleanValue(row.is_unique)
6465
- });
6466
- return Array.from(tableMap2.values());
6467
- }
6468
- async inspectMySQL() {
6469
- const tableRows = await this.runQueryRows(MYSQL_TABLES_QUERY);
6470
- const tableMap2 = this.createTableMap(
6471
- tableRows.map((row) => ({
6472
- schemaName: toOptionalStringValue(row.schema_name),
6473
- tableName: toStringValue(row.table_name)
6474
- }))
6475
- );
6476
- const columnsRows = await this.runQueryRows(MYSQL_COLUMNS_QUERY);
6477
- for (const row of columnsRows) {
6478
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6479
- if (!table) {
6480
- continue;
6481
- }
6482
- const column = {
6483
- name: toStringValue(row.column_name),
6484
- type: toStringValue(row.data_type),
6485
- isNullable: toBooleanValue(row.is_nullable),
6486
- defaultValue: row.column_default ?? null,
6487
- isPrimaryKey: false
6488
- };
6489
- table.columns.push(column);
6490
- }
6491
- const primaryKeyRows = await this.runQueryRows(MYSQL_PRIMARY_KEYS_QUERY);
6492
- for (const row of primaryKeyRows) {
6493
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6494
- if (!table) {
6495
- continue;
6496
- }
6497
- const columnName = toStringValue(row.column_name);
6498
- table.primaryKey.push(columnName);
6499
- const column = table.columns.find((entry) => entry.name === columnName);
6500
- if (column) {
6501
- column.isPrimaryKey = true;
6502
- }
6503
- }
6504
- const foreignKeyRows = await this.runQueryRows(MYSQL_FOREIGN_KEYS_QUERY);
6505
- for (const row of foreignKeyRows) {
6506
- const table = this.getTableFromRow(tableMap2, row, "table_name", "schema_name");
6507
- if (!table) {
6508
- continue;
6509
- }
6510
- const foreignKey = {
6511
- name: toOptionalStringValue(row.constraint_name),
6512
- column: toStringValue(row.column_name),
6513
- referencedSchema: toOptionalStringValue(row.referenced_schema_name),
6514
- referencedTable: toStringValue(row.referenced_table_name),
6515
- referencedColumn: toStringValue(row.referenced_column_name)
6516
- };
6517
- table.foreignKeys.push(foreignKey);
6518
- }
6519
- const indexRows = await this.runQueryRows(MYSQL_INDEXES_QUERY);
6520
- this.applyIndexRows(tableMap2, indexRows, "table_name", "schema_name", {
6521
- indexNameField: "index_name",
6522
- columnField: "column_name",
6523
- positionField: "seq_in_index",
6524
- uniqueResolver: (row) => !toBooleanValue(row.non_unique)
6525
- });
6526
- return Array.from(tableMap2.values());
6527
- }
6528
- async inspectSQLite() {
6529
- const tableRows = await this.runQueryRows(SQLITE_TABLES_QUERY);
6530
- const tableMap2 = this.createTableMap(
6531
- tableRows.map((row) => ({
6532
- tableName: toStringValue(row.table_name)
6533
- }))
6534
- );
6535
- for (const table of tableMap2.values()) {
6536
- const tableLiteral = escapeSqliteStringLiteral(table.name);
6537
- const columnRows = await this.runQueryRows(`PRAGMA table_info('${tableLiteral}')`);
6538
- const primaryKeyColumns = [];
6539
- for (const row of columnRows) {
6540
- const pkPosition = toNumberValue(row.pk);
6541
- const columnName = toStringValue(row.name);
6542
- if (pkPosition > 0) {
6543
- primaryKeyColumns.push({ position: pkPosition, column: columnName });
6544
- }
6545
- const column = {
6546
- name: columnName,
6547
- type: toStringValue(row.type),
6548
- isNullable: !toBooleanValue(row.notnull),
6549
- defaultValue: row.dflt_value ?? null,
6550
- isPrimaryKey: pkPosition > 0
6551
- };
6552
- table.columns.push(column);
6553
- }
6554
- table.primaryKey = sortColumnsByPosition(primaryKeyColumns);
6555
- const foreignKeyRows = await this.runQueryRows(`PRAGMA foreign_key_list('${tableLiteral}')`);
6556
- for (const row of foreignKeyRows) {
6557
- const foreignKey = {
6558
- column: toStringValue(row.from),
6559
- referencedTable: toStringValue(row.table),
6560
- referencedColumn: toStringValue(row.to)
6561
- };
6562
- table.foreignKeys.push(foreignKey);
6563
- }
6564
- const indexListRows = await this.runQueryRows(`PRAGMA index_list('${tableLiteral}')`);
6565
- for (const indexRow of indexListRows) {
6566
- const indexName = toStringValue(indexRow.name);
6567
- if (!indexName || toStringValue(indexRow.origin) === "pk") {
6568
- continue;
6569
- }
6570
- const indexNameLiteral = escapeSqliteStringLiteral(indexName);
6571
- const indexInfoRows = await this.runQueryRows(`PRAGMA index_info('${indexNameLiteral}')`);
6572
- const indexColumns = sortColumnsByPosition(
6573
- indexInfoRows.map((row) => ({
6574
- position: toNumberValue(row.seqno),
6575
- column: toStringValue(row.name)
6576
- }))
6577
- );
6578
- const index = {
6579
- name: indexName,
6580
- isUnique: toBooleanValue(indexRow.unique),
6581
- columns: indexColumns
6582
- };
6583
- table.indexes.push(index);
6584
- }
6585
- }
6586
- return Array.from(tableMap2.values());
6587
- }
6588
- applyIndexRows(tableMap2, rows, tableField, schemaField, config) {
6589
- const grouped = /* @__PURE__ */ new Map();
6590
- for (const row of rows) {
6591
- const table = this.getTableFromRow(tableMap2, row, tableField, schemaField);
6592
- if (!table) {
6593
- continue;
6594
- }
6595
- const indexName = toStringValue(row[config.indexNameField]);
6596
- if (!indexName) {
6597
- continue;
6598
- }
6599
- const groupKey = `${table.schema ?? ""}.${table.name}.${indexName}`;
6600
- const entry = grouped.get(groupKey) ?? {
6601
- table,
6602
- indexName,
6603
- isUnique: config.uniqueResolver(row),
6604
- columnsByPosition: []
6605
- };
6606
- entry.columnsByPosition.push({
6607
- position: toNumberValue(row[config.positionField]),
6608
- column: toStringValue(row[config.columnField])
6609
- });
6610
- grouped.set(groupKey, entry);
6611
- }
6612
- for (const entry of grouped.values()) {
6613
- const index = {
6614
- name: entry.indexName,
6615
- isUnique: entry.isUnique,
6616
- columns: sortColumnsByPosition(entry.columnsByPosition)
6617
- };
6618
- entry.table.indexes.push(index);
6619
- }
6620
- }
6621
6613
  };
6622
6614
  var logger14 = core.createLogger("agentforge:tools:data:relational:schema-validator");
6623
6615
  function validateTableExists(schema, tableName) {