11/**
2- * PGPM naming spec v1 — canonical, derived change paths.
2+ * Object identity — the canonical, Postgres-native answer to "what object is
3+ * this statement about?".
34 *
4- * A change path is never authored and never identity: it is a pure projection
5- * of an object's identity through this spec. Objects (content-addressed ASTs
6- * + dependency edges) are the source of truth; paths are re-derivable at any
7- * time, so regrouping, renaming schemes, or repartitioning packages can never
8- * break identity-keyed consumers (diff, dependency resolution).
5+ * Identity is the key used by dependency graphs, semantic diffing, and any
6+ * downstream naming scheme. It is a pure function of classifier facts —
7+ * grounded in the parser's node taxonomy (`CreateStmt`, `CreateTrigStmt`,
8+ * `IndexStmt`, ...), never in surface syntax like RangeVars. Rendering an
9+ * identity to a change path (e.g. a pgpm module layout) is deliberately NOT
10+ * defined here: paths are derived projections that belong to whichever
11+ * packaging layer consumes the identity, so nothing is ever attached to them.
912 *
1013 * Identity tuple: `(kind, schema, name, table?)` — `table` scopes objects
1114 * that are only unique per table (triggers, policies, indexes, constraints,
12- * seed data). Function overloads share a path in v1 (disambiguation via a
13- * signature suffix is reserved for a future spec version).
14- *
15- * Canonical templates (matching the conventions used across constructive-db
16- * deploy trees):
17- *
18- * schema schemas/{schema}/schema
19- * table schemas/{schema}/tables/{table}/table
20- * trigger schemas/{schema}/tables/{table}/triggers/{name}
21- * policy schemas/{schema}/tables/{table}/policies/{name}
22- * index schemas/{schema}/tables/{table}/indexes/{name}
23- * constraint schemas/{schema}/tables/{table}/constraints/{name}
24- * seed_dml schemas/{schema}/tables/{table}/fixtures/{name}
25- * function schemas/{schema}/procedures/{name}
26- * view schemas/{schema}/views/{name}
27- * type schemas/{schema}/types/{name}
28- * sequence schemas/{schema}/sequences/{name}
29- * extension extensions/{name}
30- * role roles/{name}
15+ * seed data). Function overloads share an identity for now (signature
16+ * disambiguation is a planned refinement).
3117 */
3218import { StatementFacts } from './facts' ;
3319
34- /** Spec version, so bundles/modules can declare which scheme derived their paths. */
35- export const PGPM_NAMING_SPEC_VERSION = 1 ;
36-
37- /** The kinds of objects the naming spec assigns paths to. */
20+ /** The kinds of objects an identity can describe. */
3821export type ObjectIdentityKind =
3922 | 'schema'
4023 | 'extension'
@@ -52,8 +35,8 @@ export type ObjectIdentityKind =
5235 | 'other' ;
5336
5437/**
55- * The identity of a database object — what a change path is derived from.
56- * Identity is the diff/dependency key; the path is only its rendering.
38+ * The identity of a database object. Identity is the diff/dependency key;
39+ * any path or name is only a downstream rendering of it .
5740 */
5841export interface ObjectIdentity {
5942 kind : ObjectIdentityKind ;
@@ -65,32 +48,6 @@ export interface ObjectIdentity {
6548 table ?: string ;
6649}
6750
68- /** Kinds whose objects are scoped to (and only unique within) a table. */
69- const TABLE_SCOPED = new Set < ObjectIdentityKind > ( [
70- 'trigger' ,
71- 'policy' ,
72- 'index' ,
73- 'constraint' ,
74- 'seed_dml'
75- ] ) ;
76-
77- /** Directory names for schema-scoped object kinds. */
78- const SCHEMA_DIRS : Partial < Record < ObjectIdentityKind , string > > = {
79- view : 'views' ,
80- sequence : 'sequences' ,
81- type : 'types' ,
82- function : 'procedures'
83- } ;
84-
85- /** Directory names for table-scoped object kinds. */
86- const TABLE_DIRS : Partial < Record < ObjectIdentityKind , string > > = {
87- trigger : 'triggers' ,
88- policy : 'policies' ,
89- index : 'indexes' ,
90- constraint : 'constraints' ,
91- seed_dml : 'fixtures'
92- } ;
93-
9451/**
9552 * Derive the identity of the object a statement primarily creates or
9653 * targets, or `null` when the statement creates nothing (grants, comments —
@@ -157,40 +114,3 @@ export function identityOf(facts: StatementFacts): ObjectIdentity | null {
157114 return { kind : 'other' , schema : created . schema , name : created . name } ;
158115 }
159116}
160-
161- /**
162- * Render an identity to its canonical pgpm change path (naming spec v1).
163- * Total: every identity gets a deterministic path.
164- */
165- export function pathFor ( identity : ObjectIdentity ) : string {
166- const { kind, name } = identity ;
167- const schema = identity . schema ?? 'public' ;
168-
169- if ( kind === 'schema' ) return `schemas/${ name } /schema` ;
170- if ( kind === 'extension' ) return `extensions/${ name } ` ;
171- if ( kind === 'role' ) return `roles/${ name } ` ;
172- if ( kind === 'table' ) return `schemas/${ schema } /tables/${ name } /table` ;
173-
174- if ( TABLE_SCOPED . has ( kind ) ) {
175- const dir = TABLE_DIRS [ kind ] ! ;
176- if ( identity . table && identity . table !== name ) {
177- return `schemas/${ schema } /tables/${ identity . table } /${ dir } /${ name } ` ;
178- }
179- // Table-scoped object whose table equals the target (ALTER TABLE
180- // constraints, seed data keyed by table).
181- return `schemas/${ schema } /tables/${ identity . table ?? name } /${ dir } /${ name } ` ;
182- }
183-
184- const dir = SCHEMA_DIRS [ kind ] ;
185- if ( dir ) return `schemas/${ schema } /${ dir } /${ name } ` ;
186- return `schemas/${ schema } /objects/${ name } ` ;
187- }
188-
189- /**
190- * Convenience: canonical change path for a statement, or `null` when the
191- * statement has no identity of its own.
192- */
193- export function changePathFor ( facts : StatementFacts ) : string | null {
194- const identity = identityOf ( facts ) ;
195- return identity ? pathFor ( identity ) : null ;
196- }
0 commit comments