@pgpmjs/transform 0.18.0 → 0.20.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.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Sub-object identities: the column or constraint a single `ALTER TABLE`
3
+ * statement adds.
4
+ *
5
+ * `identityOf` summarizes an ALTER TABLE by the table it targets — the right
6
+ * grouping key for object-level changes, but lossy one level down: the added
7
+ * column's `colname` and the added constraint's `conname` stay behind in the
8
+ * raw parse node (`facts.stmt`). This module recovers them, giving the
9
+ * change-granularity pipeline a stable identity (and naming-spec path) for
10
+ * every alteration.
11
+ */
12
+ import type { ObjectIdentity } from '@pgpmjs/naming-spec';
13
+ import type { StatementFacts } from '@pgsql/transform';
14
+ /**
15
+ * The column or constraint a one-command `ALTER TABLE .. ADD COLUMN` /
16
+ * `ADD CONSTRAINT` statement adds, as a naming-spec identity
17
+ * (`kind: 'column' | 'constraint'`, `table` set). Unnamed constraints get
18
+ * their Postgres default name. Returns `null` for anything else — multi-
19
+ * command ALTERs, other subtypes, non-ALTER statements — so callers fall
20
+ * back to object-level grouping.
21
+ */
22
+ export declare function subObjectIdentityOf(facts: StatementFacts): ObjectIdentity | null;
23
+ /**
24
+ * Rewrite a script so every unnamed `ALTER TABLE .. ADD <constraint>` carries
25
+ * its Postgres default name (`ADD PRIMARY KEY (id)` becomes `ADD CONSTRAINT
26
+ * {table}_pkey PRIMARY KEY (id)`) — the exact name the catalog would assign
27
+ * anyway. Naming them makes each constraint change independently revertible
28
+ * (`DROP CONSTRAINT <name>`) and verifiable. Statements that need no rewrite
29
+ * keep their original text.
30
+ */
31
+ export declare function nameUnnamedConstraints(sql: string): string;
package/sub-object.js ADDED
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.subObjectIdentityOf = subObjectIdentityOf;
4
+ exports.nameUnnamedConstraints = nameUnnamedConstraints;
5
+ const plpgsql_parser_1 = require("plpgsql-parser");
6
+ const constraint_names_1 = require("./constraint-names");
7
+ /** The single AlterTableCmd of a one-command ALTER TABLE, or null. */
8
+ function singleCmd(stmt) {
9
+ const cmds = stmt.cmds ?? [];
10
+ if (cmds.length !== 1)
11
+ return null;
12
+ return cmds[0].AlterTableCmd ?? null;
13
+ }
14
+ /**
15
+ * The column or constraint a one-command `ALTER TABLE .. ADD COLUMN` /
16
+ * `ADD CONSTRAINT` statement adds, as a naming-spec identity
17
+ * (`kind: 'column' | 'constraint'`, `table` set). Unnamed constraints get
18
+ * their Postgres default name. Returns `null` for anything else — multi-
19
+ * command ALTERs, other subtypes, non-ALTER statements — so callers fall
20
+ * back to object-level grouping.
21
+ */
22
+ function subObjectIdentityOf(facts) {
23
+ const stmt = facts.stmt?.AlterTableStmt;
24
+ if (!stmt?.relation?.relname)
25
+ return null;
26
+ const cmd = singleCmd(stmt);
27
+ if (!cmd)
28
+ return null;
29
+ const schema = stmt.relation.schemaname ?? null;
30
+ const table = stmt.relation.relname;
31
+ if (cmd.subtype === 'AT_AddColumn' && cmd.def?.ColumnDef?.colname) {
32
+ return { kind: 'column', schema, name: cmd.def.ColumnDef.colname, table };
33
+ }
34
+ if (cmd.subtype === 'AT_AddConstraint' && cmd.def?.Constraint) {
35
+ const constraint = cmd.def.Constraint;
36
+ const name = constraint.conname ?? (0, constraint_names_1.defaultConstraintName)(table, constraint);
37
+ if (!name)
38
+ return null;
39
+ return { kind: 'constraint', schema, name, table };
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * Rewrite a script so every unnamed `ALTER TABLE .. ADD <constraint>` carries
45
+ * its Postgres default name (`ADD PRIMARY KEY (id)` becomes `ADD CONSTRAINT
46
+ * {table}_pkey PRIMARY KEY (id)`) — the exact name the catalog would assign
47
+ * anyway. Naming them makes each constraint change independently revertible
48
+ * (`DROP CONSTRAINT <name>`) and verifiable. Statements that need no rewrite
49
+ * keep their original text.
50
+ */
51
+ function nameUnnamedConstraints(sql) {
52
+ const parsed = (0, plpgsql_parser_1.parseSync)(sql);
53
+ const pieces = [];
54
+ for (const raw of parsed.sql.stmts) {
55
+ const node = raw.stmt;
56
+ const stmt = node.AlterTableStmt;
57
+ const table = stmt?.relation?.relname;
58
+ let rewritten = false;
59
+ if (stmt && table) {
60
+ for (const cmd of stmt.cmds ?? []) {
61
+ const at = cmd.AlterTableCmd;
62
+ const constraint = at?.subtype === 'AT_AddConstraint' ? at.def?.Constraint : undefined;
63
+ if (constraint && !constraint.conname) {
64
+ const name = (0, constraint_names_1.defaultConstraintName)(table, constraint);
65
+ if (name) {
66
+ constraint.conname = name;
67
+ rewritten = true;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ if (rewritten) {
73
+ pieces.push(`${plpgsql_parser_1.Deparser.deparse(node, { pretty: true })};`);
74
+ }
75
+ else {
76
+ const start = raw.stmt_location ?? 0;
77
+ const len = raw.stmt_len;
78
+ const text = len === undefined ? sql.slice(start) : sql.slice(start, start + len);
79
+ const trimmed = text.trim();
80
+ pieces.push(trimmed.endsWith(';') ? trimmed : `${trimmed};`);
81
+ }
82
+ }
83
+ return pieces.join('\n\n');
84
+ }