pg-admin-mcp 0.0.0-stage → 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 +608 -2
- package/dist/config/env.js +67 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/profiles.js +257 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/core/audit-context.js +21 -0
- package/dist/core/audit-context.js.map +1 -0
- package/dist/core/audit.js +91 -0
- package/dist/core/audit.js.map +1 -0
- package/dist/core/brands.js +24 -0
- package/dist/core/brands.js.map +1 -0
- package/dist/core/classifier.js +279 -0
- package/dist/core/classifier.js.map +1 -0
- package/dist/core/errors.js +197 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/format.js +258 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/guards.js +513 -0
- package/dist/core/guards.js.map +1 -0
- package/dist/core/identifiers.js +431 -0
- package/dist/core/identifiers.js.map +1 -0
- package/dist/core/limits.js +79 -0
- package/dist/core/limits.js.map +1 -0
- package/dist/core/logger.js +34 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paginate.js +195 -0
- package/dist/core/paginate.js.map +1 -0
- package/dist/core/paths.js +392 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/policy.js +98 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/shutdown.js +10 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/stdout-guard.js +25 -0
- package/dist/core/stdout-guard.js.map +1 -0
- package/dist/db/catalog.js +1006 -0
- package/dist/db/catalog.js.map +1 -0
- package/dist/db/pool.js +158 -0
- package/dist/db/pool.js.map +1 -0
- package/dist/db/session.js +258 -0
- package/dist/db/session.js.map +1 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.js +88 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/runtime/binaries.js +356 -0
- package/dist/runtime/binaries.js.map +1 -0
- package/dist/runtime/env-file.js +62 -0
- package/dist/runtime/env-file.js.map +1 -0
- package/dist/runtime/environment.js +34 -0
- package/dist/runtime/environment.js.map +1 -0
- package/dist/server.js +106 -0
- package/dist/server.js.map +1 -0
- package/dist/snapshot/capture.js +189 -0
- package/dist/snapshot/capture.js.map +1 -0
- package/dist/snapshot/diff.js +254 -0
- package/dist/snapshot/diff.js.map +1 -0
- package/dist/snapshot/migrate.js +1596 -0
- package/dist/snapshot/migrate.js.map +1 -0
- package/dist/snapshot/model.js +80 -0
- package/dist/snapshot/model.js.map +1 -0
- package/dist/tools/_archive_meta.js +138 -0
- package/dist/tools/_archive_meta.js.map +1 -0
- package/dist/tools/_batch_shared.js +73 -0
- package/dist/tools/_batch_shared.js.map +1 -0
- package/dist/tools/_export_format.js +107 -0
- package/dist/tools/_export_format.js.map +1 -0
- package/dist/tools/_object_kinds.js +97 -0
- package/dist/tools/_object_kinds.js.map +1 -0
- package/dist/tools/_relation_detail.js +55 -0
- package/dist/tools/_relation_detail.js.map +1 -0
- package/dist/tools/_shared.js +17 -0
- package/dist/tools/_shared.js.map +1 -0
- package/dist/tools/_snapshot_io.js +238 -0
- package/dist/tools/_snapshot_io.js.map +1 -0
- package/dist/tools/admin/_shared.js +18 -0
- package/dist/tools/admin/_shared.js.map +1 -0
- package/dist/tools/admin/extensions.js +80 -0
- package/dist/tools/admin/extensions.js.map +1 -0
- package/dist/tools/admin/grants.js +207 -0
- package/dist/tools/admin/grants.js.map +1 -0
- package/dist/tools/admin/index.js +138 -0
- package/dist/tools/admin/index.js.map +1 -0
- package/dist/tools/admin/maintenance.js +106 -0
- package/dist/tools/admin/maintenance.js.map +1 -0
- package/dist/tools/admin/roles.js +144 -0
- package/dist/tools/admin/roles.js.map +1 -0
- package/dist/tools/admin/sessions.js +104 -0
- package/dist/tools/admin/sessions.js.map +1 -0
- package/dist/tools/admin/stats.js +63 -0
- package/dist/tools/admin/stats.js.map +1 -0
- package/dist/tools/backup.js +288 -0
- package/dist/tools/backup.js.map +1 -0
- package/dist/tools/connection_status.js +138 -0
- package/dist/tools/connection_status.js.map +1 -0
- package/dist/tools/copy.js +355 -0
- package/dist/tools/copy.js.map +1 -0
- package/dist/tools/delete_batch.js +73 -0
- package/dist/tools/delete_batch.js.map +1 -0
- package/dist/tools/describe_object.js +87 -0
- package/dist/tools/describe_object.js.map +1 -0
- package/dist/tools/execute_sql.js +395 -0
- package/dist/tools/execute_sql.js.map +1 -0
- package/dist/tools/explain.js +134 -0
- package/dist/tools/explain.js.map +1 -0
- package/dist/tools/export.js +215 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/get_schema.js +148 -0
- package/dist/tools/get_schema.js.map +1 -0
- package/dist/tools/index.js +40 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/insert_batch.js +212 -0
- package/dist/tools/insert_batch.js.map +1 -0
- package/dist/tools/list_objects.js +160 -0
- package/dist/tools/list_objects.js.map +1 -0
- package/dist/tools/prepare_migration.js +112 -0
- package/dist/tools/prepare_migration.js.map +1 -0
- package/dist/tools/restore.js +301 -0
- package/dist/tools/restore.js.map +1 -0
- package/dist/tools/schema_diff.js +79 -0
- package/dist/tools/schema_diff.js.map +1 -0
- package/dist/tools/schema_snapshot.js +57 -0
- package/dist/tools/schema_snapshot.js.map +1 -0
- package/dist/tools/select.js +162 -0
- package/dist/tools/select.js.map +1 -0
- package/dist/tools/update_batch.js +154 -0
- package/dist/tools/update_batch.js.map +1 -0
- package/package.json +47 -5
package/dist/server.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { performance } from 'node:perf_hooks';
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
4
|
+
import { loadProfiles } from './config/profiles.js';
|
|
5
|
+
import { auditLog } from './core/audit.js';
|
|
6
|
+
import { withAuditContext } from './core/audit-context.js';
|
|
7
|
+
import { PgMcpError } from './core/errors.js';
|
|
8
|
+
import { registerResources } from './resources/index.js';
|
|
9
|
+
import { tools } from './tools/index.js';
|
|
10
|
+
function version() {
|
|
11
|
+
try {
|
|
12
|
+
const pkg = createRequire(import.meta.url)('../package.json');
|
|
13
|
+
if (typeof pkg === 'object' && pkg !== null && 'version' in pkg && typeof pkg.version === 'string') {
|
|
14
|
+
return pkg.version;
|
|
15
|
+
}
|
|
16
|
+
return '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return '0.0.0';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Reads `args.profile` without assuming it exists — `args` is whatever the SDK validated against the tool's own schema, seen here only as `unknown`. */
|
|
23
|
+
function extractProfileAlias(args) {
|
|
24
|
+
if (typeof args !== 'object' || args === null || !('profile' in args))
|
|
25
|
+
return undefined;
|
|
26
|
+
const profile = args.profile;
|
|
27
|
+
return typeof profile === 'string' ? profile : undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Pulls an error code out of a tool's own `{ isError: true }` result, when it bothered to attach one via `structuredContent`. */
|
|
30
|
+
function extractErrorCode(result) {
|
|
31
|
+
if (!('structuredContent' in result))
|
|
32
|
+
return 'UNKNOWN';
|
|
33
|
+
const structuredContent = result.structuredContent;
|
|
34
|
+
if (typeof structuredContent !== 'object' || structuredContent === null || !('code' in structuredContent)) {
|
|
35
|
+
return 'UNKNOWN';
|
|
36
|
+
}
|
|
37
|
+
const code = structuredContent.code;
|
|
38
|
+
return typeof code === 'string' ? code : 'UNKNOWN';
|
|
39
|
+
}
|
|
40
|
+
function isErrorResult(result) {
|
|
41
|
+
return 'isError' in result && result.isError === true;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Wraps `tool.handler` so every registered call is audited — the one audit
|
|
45
|
+
* point the whole server funnels through, per `docs/design.md`'s promise of
|
|
46
|
+
* an opt-in JSONL log. `auditLog` is itself inert unless `PG_MCP_AUDIT_PATH`
|
|
47
|
+
* is set, so this wrapper costs nothing when audit is off.
|
|
48
|
+
*
|
|
49
|
+
* `profile`/`envClass` are resolved the same way every tool resolves them
|
|
50
|
+
* (`loadProfiles().get(args.profile)`), but defensively: an unknown alias, a
|
|
51
|
+
* misconfigured profile, or `PG_MCP_PROFILES` being unset must never turn
|
|
52
|
+
* into a failed tool call, so a lookup failure here only degrades what gets
|
|
53
|
+
* audited, never the call itself.
|
|
54
|
+
*/
|
|
55
|
+
export function wrapForAudit(tool) {
|
|
56
|
+
return async (args, ctx) => {
|
|
57
|
+
const start = performance.now();
|
|
58
|
+
const alias = extractProfileAlias(args);
|
|
59
|
+
let profile = alias ?? '<default>';
|
|
60
|
+
let envClass = 'unknown';
|
|
61
|
+
try {
|
|
62
|
+
const resolved = loadProfiles().get(alias);
|
|
63
|
+
profile = resolved.alias;
|
|
64
|
+
envClass = resolved.envClass;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Fall back to the alias (or '<default>') and envClass 'unknown' — see doc comment.
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const { result, contributed } = await withAuditContext(async () => tool.handler(args, ctx));
|
|
71
|
+
const durationMs = performance.now() - start;
|
|
72
|
+
const outcome = isErrorResult(result) ? 'error' : 'ok';
|
|
73
|
+
auditLog({
|
|
74
|
+
tool: tool.name,
|
|
75
|
+
profile,
|
|
76
|
+
envClass,
|
|
77
|
+
durationMs,
|
|
78
|
+
outcome,
|
|
79
|
+
...(outcome === 'error' ? { errorCode: extractErrorCode(result) } : {}),
|
|
80
|
+
...contributed,
|
|
81
|
+
});
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
const durationMs = performance.now() - start;
|
|
86
|
+
const errorCode = err instanceof PgMcpError ? err.code : 'UNCAUGHT';
|
|
87
|
+
auditLog({ tool: tool.name, profile, envClass, durationMs, outcome: 'error', errorCode });
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function createServer() {
|
|
93
|
+
const server = new McpServer({ name: 'pg-admin-mcp', version: version() }, {
|
|
94
|
+
capabilities: { tools: {}, resources: {} },
|
|
95
|
+
instructions: 'PostgreSQL administration over MCP. Every tool takes an optional `profile` alias; ' +
|
|
96
|
+
'writes, DDL, admin operations and backups are opt-in per profile and refuse by default. ' +
|
|
97
|
+
'Mutating tools are dry-run first: call once to preview, then re-call with `confirm: true` ' +
|
|
98
|
+
'and the returned `expect` object.',
|
|
99
|
+
});
|
|
100
|
+
for (const tool of tools) {
|
|
101
|
+
server.registerTool(tool.name, tool.config, wrapForAudit(tool));
|
|
102
|
+
}
|
|
103
|
+
registerResources(server);
|
|
104
|
+
return server;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { PgMcpError } from '../core/errors.js';
|
|
2
|
+
import { getConstraintDefsBatch, getCurrentDatabase, getIndexesBatch, getPoliciesBatch, getRelationExtrasBatch, getSnapshotColumnsBatch, getTriggersBatch, listEnumTypes, listExtensions, listFunctionSources, listRelations, listSchemas, listSequenceDetails, } from '../db/catalog.js';
|
|
3
|
+
import { withTx } from '../db/session.js';
|
|
4
|
+
import { SNAPSHOT_FORMAT_VERSION, functionKey, sortByKey, } from './model.js';
|
|
5
|
+
export async function captureSnapshot(profile, scope = {}) {
|
|
6
|
+
return withTx(profile, (client) => capture(client, profile, scope), {
|
|
7
|
+
readOnly: true,
|
|
8
|
+
isolation: 'repeatable read',
|
|
9
|
+
searchPath: 'pg_catalog',
|
|
10
|
+
operation: 'schema snapshot',
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async function capture(client, profile, scope) {
|
|
14
|
+
const database = await getCurrentDatabase(client);
|
|
15
|
+
const schemaInfos = await listSchemas(client, profile.schemas);
|
|
16
|
+
const names = resolveScope(schemaInfos.map((s) => s.name), scope, profile);
|
|
17
|
+
const relations = await listRelations(client, names);
|
|
18
|
+
const oids = relations.map((r) => r.oid);
|
|
19
|
+
const columns = await getSnapshotColumnsBatch(client, oids);
|
|
20
|
+
const constraints = await getConstraintDefsBatch(client, oids, ['p', 'u', 'c', 'f']);
|
|
21
|
+
const indexes = await getIndexesBatch(client, oids, { excludeConstraintBacked: true });
|
|
22
|
+
const triggers = await getTriggersBatch(client, oids);
|
|
23
|
+
const policies = await getPoliciesBatch(client, oids);
|
|
24
|
+
const extras = await getRelationExtrasBatch(client, oids);
|
|
25
|
+
const sequences = await listSequenceDetails(client, names);
|
|
26
|
+
const functions = await listFunctionSources(client, names);
|
|
27
|
+
const enums = await listEnumTypes(client, names);
|
|
28
|
+
const extensions = await listExtensions(client);
|
|
29
|
+
const inScope = new Set(names);
|
|
30
|
+
const schemas = sortByKey(schemaInfos.filter((s) => inScope.has(s.name)), (s) => s.name).map((schema) => ({
|
|
31
|
+
name: schema.name,
|
|
32
|
+
owner: schema.owner,
|
|
33
|
+
tables: sortByKey(relations.filter((r) => r.schema === schema.name && isTableKind(r.kind)), (r) => r.name).map((r) => buildTable(r, columns, constraints, indexes, triggers, policies, extras)),
|
|
34
|
+
views: buildViews(relations, schema.name, 'view', columns, indexes, triggers, extras),
|
|
35
|
+
materializedViews: buildViews(relations, schema.name, 'materialized_view', columns, indexes, triggers, extras),
|
|
36
|
+
sequences: sortByKey(sequences.filter((s) => s.schema === schema.name), (s) => s.name).map((s) => ({
|
|
37
|
+
name: s.name,
|
|
38
|
+
owner: s.owner,
|
|
39
|
+
comment: s.comment,
|
|
40
|
+
dataType: s.dataType,
|
|
41
|
+
startValue: s.startValue,
|
|
42
|
+
minValue: s.minValue,
|
|
43
|
+
maxValue: s.maxValue,
|
|
44
|
+
incrementBy: s.incrementBy,
|
|
45
|
+
cacheSize: s.cacheSize,
|
|
46
|
+
cycle: s.cycle,
|
|
47
|
+
})),
|
|
48
|
+
functions: sortByKey(functions
|
|
49
|
+
.filter((f) => f.schema === schema.name)
|
|
50
|
+
.map((f) => ({
|
|
51
|
+
name: f.name,
|
|
52
|
+
arguments: f.argTypes,
|
|
53
|
+
returns: f.returnType,
|
|
54
|
+
language: f.language,
|
|
55
|
+
kind: f.kind,
|
|
56
|
+
body: f.body,
|
|
57
|
+
comment: f.comment,
|
|
58
|
+
})), functionKey),
|
|
59
|
+
enums: sortByKey(enums.filter((e) => e.schema === schema.name), (e) => e.name).map((e) => ({ name: e.name, labels: [...e.labels], comment: e.comment })),
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
formatVersion: SNAPSHOT_FORMAT_VERSION,
|
|
63
|
+
database,
|
|
64
|
+
schemas,
|
|
65
|
+
extensions: sortByKey(extensions.map((e) => ({ name: e.name, version: e.version })), (e) => e.name),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `Profile.schemas` is the ceiling; `scope.schemas` may only narrow it. An
|
|
70
|
+
* unknown name is refused rather than silently dropped — a snapshot that
|
|
71
|
+
* quietly omits the schema the caller asked about is worse than an error, and
|
|
72
|
+
* `migrate.ts` would generate a `DROP` for every table in it.
|
|
73
|
+
*
|
|
74
|
+
* "Not in scope" and "does not exist" deliberately produce the same message:
|
|
75
|
+
* distinguishing them would turn this into a probe for schemas the profile
|
|
76
|
+
* exists to hide.
|
|
77
|
+
*/
|
|
78
|
+
function resolveScope(available, scope, profile) {
|
|
79
|
+
const sorted = sortByKey(available, (s) => s);
|
|
80
|
+
if (scope.schemas === undefined)
|
|
81
|
+
return sorted;
|
|
82
|
+
const availableSet = new Set(available);
|
|
83
|
+
const unknown = scope.schemas.filter((s) => !availableSet.has(s));
|
|
84
|
+
if (unknown.length > 0) {
|
|
85
|
+
throw new PgMcpError({
|
|
86
|
+
code: 'IDENTIFIER_UNKNOWN',
|
|
87
|
+
message: `no schema named ${unknown.map((s) => `"${s}"`).join(', ')} is available to profile "${profile.alias}"`,
|
|
88
|
+
hint: sorted.length > 0
|
|
89
|
+
? `snapshot one of these instead: ${sorted.join(', ')}`
|
|
90
|
+
: `profile "${profile.alias}" can see no schemas at all — check its PG_<ALIAS>_SCHEMAS setting and the role's USAGE grants`,
|
|
91
|
+
details: { profile: profile.alias, unknown, available: sorted },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const requested = new Set(scope.schemas);
|
|
95
|
+
return sorted.filter((s) => requested.has(s));
|
|
96
|
+
}
|
|
97
|
+
const TABLE_KINDS = new Set(['table', 'partitioned_table', 'foreign_table']);
|
|
98
|
+
function isTableKind(kind) {
|
|
99
|
+
return TABLE_KINDS.has(kind);
|
|
100
|
+
}
|
|
101
|
+
const NO_ROW_SECURITY = {
|
|
102
|
+
rowSecurityEnabled: false,
|
|
103
|
+
rowSecurityForced: false,
|
|
104
|
+
viewDefinition: null,
|
|
105
|
+
inherits: [],
|
|
106
|
+
partitionBound: null,
|
|
107
|
+
};
|
|
108
|
+
function buildTable(relation, columns, constraints, indexes, triggers, policies, extras) {
|
|
109
|
+
const own = constraints.get(relation.oid) ?? [];
|
|
110
|
+
const extra = extras.get(relation.oid) ?? NO_ROW_SECURITY;
|
|
111
|
+
const primaryKeys = own.filter((c) => c.type === 'p');
|
|
112
|
+
return {
|
|
113
|
+
name: relation.name,
|
|
114
|
+
kind: isTableKind(relation.kind) ? relation.kind : 'table',
|
|
115
|
+
owner: relation.owner,
|
|
116
|
+
comment: relation.comment,
|
|
117
|
+
inherits: [...extra.inherits],
|
|
118
|
+
partitionBound: extra.partitionBound,
|
|
119
|
+
columns: buildColumns(relation.oid, columns),
|
|
120
|
+
// A relation has at most one primary key; `[0]` is the whole set, not a pick.
|
|
121
|
+
primaryKey: primaryKeys[0] === undefined ? null : toConstraint(primaryKeys[0]),
|
|
122
|
+
foreignKeys: sortByKey(own.filter((c) => c.type === 'f').map(toForeignKey), (c) => c.name),
|
|
123
|
+
uniqueConstraints: sortByKey(own.filter((c) => c.type === 'u').map(toConstraint), (c) => c.name),
|
|
124
|
+
checkConstraints: sortByKey(own.filter((c) => c.type === 'c').map(toConstraint), (c) => c.name),
|
|
125
|
+
indexes: buildIndexes(relation.oid, indexes),
|
|
126
|
+
triggers: buildTriggers(relation.oid, triggers),
|
|
127
|
+
rowSecurity: {
|
|
128
|
+
enabled: extra.rowSecurityEnabled,
|
|
129
|
+
forced: extra.rowSecurityForced,
|
|
130
|
+
policies: sortByKey(policies.get(relation.oid) ?? [], (p) => p.name).map((p) => ({
|
|
131
|
+
name: p.name,
|
|
132
|
+
command: p.command,
|
|
133
|
+
permissive: p.permissive,
|
|
134
|
+
roles: [...p.roles],
|
|
135
|
+
using: p.using,
|
|
136
|
+
withCheck: p.withCheck,
|
|
137
|
+
})),
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function buildViews(relations, schema, kind, columns, indexes, triggers, extras) {
|
|
142
|
+
return sortByKey(relations.filter((r) => r.schema === schema && r.kind === kind), (r) => r.name).map((r) => ({
|
|
143
|
+
name: r.name,
|
|
144
|
+
kind,
|
|
145
|
+
owner: r.owner,
|
|
146
|
+
comment: r.comment,
|
|
147
|
+
definition: extras.get(r.oid)?.viewDefinition ?? null,
|
|
148
|
+
columns: buildColumns(r.oid, columns),
|
|
149
|
+
indexes: buildIndexes(r.oid, indexes),
|
|
150
|
+
triggers: buildTriggers(r.oid, triggers),
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
/** Sorted by name, not by `attnum` — see `model.ts`'s header on why physical column order is not comparable. */
|
|
154
|
+
function buildColumns(oid, columns) {
|
|
155
|
+
return sortByKey(columns.get(oid) ?? [], (c) => c.name).map((c) => ({
|
|
156
|
+
name: c.name,
|
|
157
|
+
type: c.dataType,
|
|
158
|
+
nullable: !c.notNull,
|
|
159
|
+
default: c.defaultExpr,
|
|
160
|
+
identity: c.identity,
|
|
161
|
+
generated: c.generated,
|
|
162
|
+
collation: c.collation,
|
|
163
|
+
comment: c.comment,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
function buildIndexes(oid, indexes) {
|
|
167
|
+
return sortByKey(indexes.get(oid) ?? [], (i) => i.name).map((i) => ({
|
|
168
|
+
name: i.name,
|
|
169
|
+
definition: i.definition,
|
|
170
|
+
unique: i.isUnique,
|
|
171
|
+
columns: [...i.columns],
|
|
172
|
+
predicate: i.predicate,
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
function buildTriggers(oid, triggers) {
|
|
176
|
+
return sortByKey(triggers.get(oid) ?? [], (t) => t.name).map((t) => ({
|
|
177
|
+
name: t.name,
|
|
178
|
+
timing: t.timing,
|
|
179
|
+
events: [...t.events],
|
|
180
|
+
definition: t.definition,
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
function toConstraint(c) {
|
|
184
|
+
return { name: c.name, definition: c.definition };
|
|
185
|
+
}
|
|
186
|
+
function toForeignKey(c) {
|
|
187
|
+
return { name: c.name, definition: c.definition, refSchema: c.refSchema ?? '', refTable: c.refTable ?? '' };
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/snapshot/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
+
import { PgMcpError } from '../core/errors.js';
|
|
3
|
+
import { SNAPSHOT_FORMAT_VERSION, compareKeys, functionKey, } from './model.js';
|
|
4
|
+
export function diffSnapshots(before, after) {
|
|
5
|
+
assertComparable(before, after);
|
|
6
|
+
const out = [];
|
|
7
|
+
if (before.database !== after.database) {
|
|
8
|
+
out.push({
|
|
9
|
+
kind: 'modified',
|
|
10
|
+
objectType: 'database',
|
|
11
|
+
path: before.database,
|
|
12
|
+
fields: [{ field: 'database', before: before.database, after: after.database }],
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
diffList(out, {
|
|
16
|
+
objectType: 'schema',
|
|
17
|
+
before: before.schemas,
|
|
18
|
+
after: after.schemas,
|
|
19
|
+
key: (s) => s.name,
|
|
20
|
+
path: (name) => name,
|
|
21
|
+
fields: ['owner'],
|
|
22
|
+
nested: diffSchema,
|
|
23
|
+
});
|
|
24
|
+
diffList(out, {
|
|
25
|
+
objectType: 'extension',
|
|
26
|
+
before: before.extensions,
|
|
27
|
+
after: after.extensions,
|
|
28
|
+
key: (e) => e.name,
|
|
29
|
+
path: (name) => name,
|
|
30
|
+
fields: ['version'],
|
|
31
|
+
});
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A snapshot from an older format is detected, not silently misdiagnosed. Both
|
|
36
|
+
* versions are named in the message because "which one is stale" is the only
|
|
37
|
+
* question the reader has.
|
|
38
|
+
*/
|
|
39
|
+
function assertComparable(before, after) {
|
|
40
|
+
const stale = [before, after].filter((s) => s.formatVersion !== SNAPSHOT_FORMAT_VERSION);
|
|
41
|
+
if (stale.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
throw new PgMcpError({
|
|
44
|
+
code: 'SNAPSHOT_VERSION_MISMATCH',
|
|
45
|
+
message: `cannot diff snapshots: this server reads format version ${SNAPSHOT_FORMAT_VERSION}, ` +
|
|
46
|
+
`and the two given are version ${before.formatVersion} (before) and ${after.formatVersion} (after)`,
|
|
47
|
+
hint: 'recapture the stale snapshot with postgres_schema_snapshot against the same database and diff the new one — ' +
|
|
48
|
+
'a snapshot from an older format is not comparable field-for-field, and diffing it anyway would report every ' +
|
|
49
|
+
'object in the database as modified',
|
|
50
|
+
details: { expected: SNAPSHOT_FORMAT_VERSION, before: before.formatVersion, after: after.formatVersion },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The whole engine. Merges the two key sets, walks them in {@link compareKeys}
|
|
55
|
+
* order, and emits added / removed / modified — the modified entry first, then
|
|
56
|
+
* whatever `nested` finds inside, so the output reads outside-in.
|
|
57
|
+
*/
|
|
58
|
+
function diffList(out, spec) {
|
|
59
|
+
const beforeByKey = new Map(spec.before.map((item) => [spec.key(item), item]));
|
|
60
|
+
const afterByKey = new Map(spec.after.map((item) => [spec.key(item), item]));
|
|
61
|
+
const keys = [...new Set([...beforeByKey.keys(), ...afterByKey.keys()])].sort(compareKeys);
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const b = beforeByKey.get(key);
|
|
64
|
+
const a = afterByKey.get(key);
|
|
65
|
+
const path = spec.path(key);
|
|
66
|
+
if (b === undefined) {
|
|
67
|
+
out.push({ kind: 'added', objectType: spec.objectType, path, object: a });
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (a === undefined) {
|
|
71
|
+
out.push({ kind: 'removed', objectType: spec.objectType, path, object: b });
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const fields = changedFields(b, a, spec.fields ?? []);
|
|
75
|
+
if (fields.length > 0)
|
|
76
|
+
out.push({ kind: 'modified', objectType: spec.objectType, path, fields });
|
|
77
|
+
spec.nested?.(out, path, b, a);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* `isDeepStrictEqual` rather than `===` or a JSON string compare: several model
|
|
82
|
+
* fields are string arrays (a policy's roles, an enum's labels, an index's
|
|
83
|
+
* columns), and a JSON compare would additionally report two objects with the
|
|
84
|
+
* same content but a different key insertion order as different — which a
|
|
85
|
+
* hand-built snapshot easily is.
|
|
86
|
+
*/
|
|
87
|
+
function changedFields(before, after, fields) {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const field of fields) {
|
|
90
|
+
const b = before[field];
|
|
91
|
+
const a = after[field];
|
|
92
|
+
if (!isDeepStrictEqual(b, a))
|
|
93
|
+
out.push({ field, before: b, after: a });
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
function diffSchema(out, schema, before, after) {
|
|
98
|
+
diffList(out, {
|
|
99
|
+
objectType: 'table',
|
|
100
|
+
before: before.tables,
|
|
101
|
+
after: after.tables,
|
|
102
|
+
key: (t) => t.name,
|
|
103
|
+
path: (name) => `${schema}.${name}`,
|
|
104
|
+
fields: ['kind', 'owner', 'comment', 'inherits', 'partitionBound'],
|
|
105
|
+
nested: diffTable,
|
|
106
|
+
});
|
|
107
|
+
for (const [objectType, beforeViews, afterViews] of [
|
|
108
|
+
['view', before.views, after.views],
|
|
109
|
+
['materialized_view', before.materializedViews, after.materializedViews],
|
|
110
|
+
]) {
|
|
111
|
+
diffList(out, {
|
|
112
|
+
objectType,
|
|
113
|
+
before: beforeViews,
|
|
114
|
+
after: afterViews,
|
|
115
|
+
key: (v) => v.name,
|
|
116
|
+
path: (name) => `${schema}.${name}`,
|
|
117
|
+
fields: ['owner', 'comment', 'definition'],
|
|
118
|
+
nested: diffView,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
diffList(out, {
|
|
122
|
+
objectType: 'sequence',
|
|
123
|
+
before: before.sequences,
|
|
124
|
+
after: after.sequences,
|
|
125
|
+
key: (s) => s.name,
|
|
126
|
+
path: (name) => `${schema}.${name}`,
|
|
127
|
+
fields: ['owner', 'comment', 'dataType', 'startValue', 'minValue', 'maxValue', 'incrementBy', 'cacheSize', 'cycle'],
|
|
128
|
+
});
|
|
129
|
+
diffList(out, {
|
|
130
|
+
objectType: 'function',
|
|
131
|
+
before: before.functions,
|
|
132
|
+
after: after.functions,
|
|
133
|
+
key: functionKey,
|
|
134
|
+
path: (key) => `${schema}.${key}`,
|
|
135
|
+
fields: ['returns', 'language', 'kind', 'body', 'comment'],
|
|
136
|
+
});
|
|
137
|
+
diffList(out, {
|
|
138
|
+
objectType: 'enum',
|
|
139
|
+
before: before.enums,
|
|
140
|
+
after: after.enums,
|
|
141
|
+
key: (e) => e.name,
|
|
142
|
+
path: (name) => `${schema}.${name}`,
|
|
143
|
+
fields: ['labels', 'comment'],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function diffTable(out, path, before, after) {
|
|
147
|
+
diffColumns(out, path, before.columns, after.columns);
|
|
148
|
+
// At most one primary key per table, so it is a single object rather than a
|
|
149
|
+
// keyed collection — but it still needs the added/removed/modified triple.
|
|
150
|
+
diffList(out, {
|
|
151
|
+
objectType: 'primary_key',
|
|
152
|
+
before: before.primaryKey === null ? [] : [before.primaryKey],
|
|
153
|
+
after: after.primaryKey === null ? [] : [after.primaryKey],
|
|
154
|
+
key: (c) => c.name,
|
|
155
|
+
path: (name) => `${path}.${name}`,
|
|
156
|
+
fields: ['definition'],
|
|
157
|
+
});
|
|
158
|
+
diffList(out, {
|
|
159
|
+
objectType: 'foreign_key',
|
|
160
|
+
before: before.foreignKeys,
|
|
161
|
+
after: after.foreignKeys,
|
|
162
|
+
key: (c) => c.name,
|
|
163
|
+
path: (name) => `${path}.${name}`,
|
|
164
|
+
fields: ['definition', 'refSchema', 'refTable'],
|
|
165
|
+
});
|
|
166
|
+
diffList(out, {
|
|
167
|
+
objectType: 'unique_constraint',
|
|
168
|
+
before: before.uniqueConstraints,
|
|
169
|
+
after: after.uniqueConstraints,
|
|
170
|
+
key: (c) => c.name,
|
|
171
|
+
path: (name) => `${path}.${name}`,
|
|
172
|
+
fields: ['definition'],
|
|
173
|
+
});
|
|
174
|
+
diffList(out, {
|
|
175
|
+
objectType: 'check_constraint',
|
|
176
|
+
before: before.checkConstraints,
|
|
177
|
+
after: after.checkConstraints,
|
|
178
|
+
key: (c) => c.name,
|
|
179
|
+
path: (name) => `${path}.${name}`,
|
|
180
|
+
fields: ['definition'],
|
|
181
|
+
});
|
|
182
|
+
diffIndexesAndTriggers(out, path, before, after);
|
|
183
|
+
// RLS is two flags plus a keyed collection. The flags are reported against
|
|
184
|
+
// the table itself (enabling RLS is a change to the table, not to a policy),
|
|
185
|
+
// the policies against their own paths.
|
|
186
|
+
const flags = changedFields(before.rowSecurity, after.rowSecurity, ['enabled', 'forced']);
|
|
187
|
+
if (flags.length > 0) {
|
|
188
|
+
out.push({
|
|
189
|
+
kind: 'modified',
|
|
190
|
+
objectType: 'table',
|
|
191
|
+
path,
|
|
192
|
+
fields: flags.map((f) => ({ field: `rowSecurity.${f.field}`, before: f.before, after: f.after })),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
diffList(out, {
|
|
196
|
+
objectType: 'policy',
|
|
197
|
+
before: before.rowSecurity.policies,
|
|
198
|
+
after: after.rowSecurity.policies,
|
|
199
|
+
key: (p) => p.name,
|
|
200
|
+
path: (name) => `${path}.${name}`,
|
|
201
|
+
fields: ['command', 'permissive', 'roles', 'using', 'withCheck'],
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Deliberately **not** `diffColumns`. A view's column set is derived: it is
|
|
206
|
+
* whatever its `definition` selects, and PostgreSQL has no `ALTER VIEW … ADD/
|
|
207
|
+
* DROP COLUMN` at all ("ALTER action ADD COLUMN cannot be performed on
|
|
208
|
+
* relation", "cannot drop columns from view"). Emitting `column` changes here
|
|
209
|
+
* produced entries `migrate.ts` turned into `ALTER TABLE … ADD COLUMN`
|
|
210
|
+
* statements that always fail, for the single most common view change there
|
|
211
|
+
* is. The real change is already reported — and already actionable — as the
|
|
212
|
+
* view's own `definition` field (`CREATE OR REPLACE VIEW` for a plain view;
|
|
213
|
+
* `unsupported` for a materialized one), so this would be duplication even if
|
|
214
|
+
* it were runnable.
|
|
215
|
+
*
|
|
216
|
+
* Indexes and triggers *are* independently alterable on a view (a
|
|
217
|
+
* materialized view carries real indexes; a plain view carries INSTEAD OF
|
|
218
|
+
* triggers), so those still diff.
|
|
219
|
+
*/
|
|
220
|
+
function diffView(out, path, before, after) {
|
|
221
|
+
diffIndexesAndTriggers(out, path, before, after);
|
|
222
|
+
}
|
|
223
|
+
function diffColumns(out, path, before, after) {
|
|
224
|
+
diffList(out, {
|
|
225
|
+
objectType: 'column',
|
|
226
|
+
before,
|
|
227
|
+
after,
|
|
228
|
+
key: (c) => c.name,
|
|
229
|
+
path: (name) => `${path}.${name}`,
|
|
230
|
+
fields: ['type', 'nullable', 'default', 'identity', 'generated', 'collation', 'comment'],
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function diffIndexesAndTriggers(out, path, before, after) {
|
|
234
|
+
diffList(out, {
|
|
235
|
+
objectType: 'index',
|
|
236
|
+
before: before.indexes,
|
|
237
|
+
after: after.indexes,
|
|
238
|
+
key: (i) => i.name,
|
|
239
|
+
path: (name) => `${path}.${name}`,
|
|
240
|
+
// `definition` already contains the columns and the predicate; both are
|
|
241
|
+
// kept as their own fields because "the predicate changed" is a far more
|
|
242
|
+
// legible report than a 200-character CREATE INDEX before/after pair.
|
|
243
|
+
fields: ['definition', 'unique', 'columns', 'predicate'],
|
|
244
|
+
});
|
|
245
|
+
diffList(out, {
|
|
246
|
+
objectType: 'trigger',
|
|
247
|
+
before: before.triggers,
|
|
248
|
+
after: after.triggers,
|
|
249
|
+
key: (t) => t.name,
|
|
250
|
+
path: (name) => `${path}.${name}`,
|
|
251
|
+
fields: ['timing', 'events', 'definition'],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/snapshot/diff.ts"],"names":[],"mappings":"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"}
|