@danielfgray/pg-sourcerer 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.
Files changed (145) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +104 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +133 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +47 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/errors.d.ts +129 -0
  10. package/dist/errors.d.ts.map +1 -0
  11. package/dist/errors.js +41 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/generate.d.ts +75 -0
  14. package/dist/generate.d.ts.map +1 -0
  15. package/dist/generate.js +183 -0
  16. package/dist/generate.js.map +1 -0
  17. package/dist/index.d.ts +35 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +62 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/init.d.ts +4 -0
  22. package/dist/init.d.ts.map +1 -0
  23. package/dist/init.js +229 -0
  24. package/dist/init.js.map +1 -0
  25. package/dist/ir/index.d.ts +7 -0
  26. package/dist/ir/index.d.ts.map +1 -0
  27. package/dist/ir/index.js +7 -0
  28. package/dist/ir/index.js.map +1 -0
  29. package/dist/ir/relation-graph.d.ts +113 -0
  30. package/dist/ir/relation-graph.d.ts.map +1 -0
  31. package/dist/ir/relation-graph.js +232 -0
  32. package/dist/ir/relation-graph.js.map +1 -0
  33. package/dist/ir/semantic-ir.d.ts +448 -0
  34. package/dist/ir/semantic-ir.d.ts.map +1 -0
  35. package/dist/ir/semantic-ir.js +138 -0
  36. package/dist/ir/semantic-ir.js.map +1 -0
  37. package/dist/ir/smart-tags.d.ts +24 -0
  38. package/dist/ir/smart-tags.d.ts.map +1 -0
  39. package/dist/ir/smart-tags.js +30 -0
  40. package/dist/ir/smart-tags.js.map +1 -0
  41. package/dist/lib/conjure.d.ts +431 -0
  42. package/dist/lib/conjure.d.ts.map +1 -0
  43. package/dist/lib/conjure.js +697 -0
  44. package/dist/lib/conjure.js.map +1 -0
  45. package/dist/lib/field-utils.d.ts +61 -0
  46. package/dist/lib/field-utils.d.ts.map +1 -0
  47. package/dist/lib/field-utils.js +132 -0
  48. package/dist/lib/field-utils.js.map +1 -0
  49. package/dist/lib/hex.d.ts +117 -0
  50. package/dist/lib/hex.d.ts.map +1 -0
  51. package/dist/lib/hex.js +185 -0
  52. package/dist/lib/hex.js.map +1 -0
  53. package/dist/plugins/arktype.d.ts +11 -0
  54. package/dist/plugins/arktype.d.ts.map +1 -0
  55. package/dist/plugins/arktype.js +207 -0
  56. package/dist/plugins/arktype.js.map +1 -0
  57. package/dist/plugins/effect-model.d.ts +10 -0
  58. package/dist/plugins/effect-model.d.ts.map +1 -0
  59. package/dist/plugins/effect-model.js +261 -0
  60. package/dist/plugins/effect-model.js.map +1 -0
  61. package/dist/plugins/kysely-queries.d.ts +7 -0
  62. package/dist/plugins/kysely-queries.d.ts.map +1 -0
  63. package/dist/plugins/kysely-queries.js +380 -0
  64. package/dist/plugins/kysely-queries.js.map +1 -0
  65. package/dist/plugins/sql-queries.d.ts +6 -0
  66. package/dist/plugins/sql-queries.d.ts.map +1 -0
  67. package/dist/plugins/sql-queries.js +249 -0
  68. package/dist/plugins/sql-queries.js.map +1 -0
  69. package/dist/plugins/types.d.ts +18 -0
  70. package/dist/plugins/types.d.ts.map +1 -0
  71. package/dist/plugins/types.js +263 -0
  72. package/dist/plugins/types.js.map +1 -0
  73. package/dist/plugins/zod.d.ts +11 -0
  74. package/dist/plugins/zod.d.ts.map +1 -0
  75. package/dist/plugins/zod.js +180 -0
  76. package/dist/plugins/zod.js.map +1 -0
  77. package/dist/services/artifact-store.d.ts +55 -0
  78. package/dist/services/artifact-store.d.ts.map +1 -0
  79. package/dist/services/artifact-store.js +51 -0
  80. package/dist/services/artifact-store.js.map +1 -0
  81. package/dist/services/config-loader.d.ts +45 -0
  82. package/dist/services/config-loader.d.ts.map +1 -0
  83. package/dist/services/config-loader.js +113 -0
  84. package/dist/services/config-loader.js.map +1 -0
  85. package/dist/services/emissions.d.ts +89 -0
  86. package/dist/services/emissions.d.ts.map +1 -0
  87. package/dist/services/emissions.js +194 -0
  88. package/dist/services/emissions.js.map +1 -0
  89. package/dist/services/file-builder.d.ts +81 -0
  90. package/dist/services/file-builder.d.ts.map +1 -0
  91. package/dist/services/file-builder.js +112 -0
  92. package/dist/services/file-builder.js.map +1 -0
  93. package/dist/services/file-writer.d.ts +57 -0
  94. package/dist/services/file-writer.d.ts.map +1 -0
  95. package/dist/services/file-writer.js +76 -0
  96. package/dist/services/file-writer.js.map +1 -0
  97. package/dist/services/inflection.d.ts +227 -0
  98. package/dist/services/inflection.d.ts.map +1 -0
  99. package/dist/services/inflection.js +350 -0
  100. package/dist/services/inflection.js.map +1 -0
  101. package/dist/services/introspection.d.ts +46 -0
  102. package/dist/services/introspection.d.ts.map +1 -0
  103. package/dist/services/introspection.js +99 -0
  104. package/dist/services/introspection.js.map +1 -0
  105. package/dist/services/ir-builder.d.ts +46 -0
  106. package/dist/services/ir-builder.d.ts.map +1 -0
  107. package/dist/services/ir-builder.js +923 -0
  108. package/dist/services/ir-builder.js.map +1 -0
  109. package/dist/services/ir.d.ts +28 -0
  110. package/dist/services/ir.d.ts.map +1 -0
  111. package/dist/services/ir.js +25 -0
  112. package/dist/services/ir.js.map +1 -0
  113. package/dist/services/pg-types.d.ts +197 -0
  114. package/dist/services/pg-types.d.ts.map +1 -0
  115. package/dist/services/pg-types.js +274 -0
  116. package/dist/services/pg-types.js.map +1 -0
  117. package/dist/services/plugin-meta.d.ts +33 -0
  118. package/dist/services/plugin-meta.d.ts.map +1 -0
  119. package/dist/services/plugin-meta.js +24 -0
  120. package/dist/services/plugin-meta.js.map +1 -0
  121. package/dist/services/plugin-runner.d.ts +52 -0
  122. package/dist/services/plugin-runner.d.ts.map +1 -0
  123. package/dist/services/plugin-runner.js +182 -0
  124. package/dist/services/plugin-runner.js.map +1 -0
  125. package/dist/services/plugin.d.ts +286 -0
  126. package/dist/services/plugin.d.ts.map +1 -0
  127. package/dist/services/plugin.js +132 -0
  128. package/dist/services/plugin.js.map +1 -0
  129. package/dist/services/smart-tags-parser.d.ts +37 -0
  130. package/dist/services/smart-tags-parser.d.ts.map +1 -0
  131. package/dist/services/smart-tags-parser.js +79 -0
  132. package/dist/services/smart-tags-parser.js.map +1 -0
  133. package/dist/services/symbols.d.ts +85 -0
  134. package/dist/services/symbols.d.ts.map +1 -0
  135. package/dist/services/symbols.js +128 -0
  136. package/dist/services/symbols.js.map +1 -0
  137. package/dist/services/type-hints.d.ts +62 -0
  138. package/dist/services/type-hints.d.ts.map +1 -0
  139. package/dist/services/type-hints.js +117 -0
  140. package/dist/services/type-hints.js.map +1 -0
  141. package/dist/testing.d.ts +77 -0
  142. package/dist/testing.d.ts.map +1 -0
  143. package/dist/testing.js +84 -0
  144. package/dist/testing.js.map +1 -0
  145. package/package.json +74 -0
@@ -0,0 +1,448 @@
1
+ /**
2
+ * Semantic IR - Intermediate Representation of database schema
3
+ *
4
+ * This is the core data structure that plugins consume.
5
+ * It represents semantic intent, not code.
6
+ */
7
+ import type { PgAttribute, PgClass, PgType, PgProc } from "@pg-sourcerer/pg-introspection";
8
+ import type { SmartTags, ShapeKind } from "./smart-tags.js";
9
+ /**
10
+ * Information about a domain type's underlying base type.
11
+ * Used for type resolution when the column type is a domain.
12
+ */
13
+ export interface DomainBaseTypeInfo {
14
+ /** Base type name (e.g., "citext" for a domain over citext) */
15
+ readonly typeName: string;
16
+ /** Base type OID (for OID-based type mapping) */
17
+ readonly typeOid: number;
18
+ /** Base type namespace OID (for extension lookup) */
19
+ readonly namespaceOid: string;
20
+ /** Base type category (e.g., 'S' for string) */
21
+ readonly category: string;
22
+ }
23
+ /**
24
+ * A field within a shape - represents a column with semantic context
25
+ */
26
+ export interface Field {
27
+ /** Inflected field name (camelCase) */
28
+ readonly name: string;
29
+ /** Original PostgreSQL column name */
30
+ readonly columnName: string;
31
+ /** Raw attribute from pg-introspection */
32
+ readonly pgAttribute: PgAttribute;
33
+ /** Can be NULL at runtime */
34
+ readonly nullable: boolean;
35
+ /** Optional in this shape (e.g., has default for insert) */
36
+ readonly optional: boolean;
37
+ /** Has DEFAULT or is GENERATED */
38
+ readonly hasDefault: boolean;
39
+ /** GENERATED ALWAYS column */
40
+ readonly isGenerated: boolean;
41
+ /** IDENTITY column */
42
+ readonly isIdentity: boolean;
43
+ /** PostgreSQL array type */
44
+ readonly isArray: boolean;
45
+ /** For arrays, the element type name */
46
+ readonly elementTypeName?: string;
47
+ /** If the column type is a domain, info about the underlying base type */
48
+ readonly domainBaseType?: DomainBaseTypeInfo;
49
+ /** Smart tags from comment */
50
+ readonly tags: SmartTags;
51
+ /** Plugin-attached data (extensible, keyed by plugin name) */
52
+ readonly extensions: ReadonlyMap<string, unknown>;
53
+ /** Permissions for the connected role */
54
+ readonly permissions: FieldPermissions;
55
+ }
56
+ /**
57
+ * A shape is a structure with fields - the semantic description
58
+ * that can become a TypeScript type, Zod schema, etc.
59
+ */
60
+ export interface Shape {
61
+ /** e.g., "UserRow", "UserInsert" */
62
+ readonly name: string;
63
+ /** The kind of shape */
64
+ readonly kind: ShapeKind;
65
+ /** Fields in this shape */
66
+ readonly fields: readonly Field[];
67
+ }
68
+ /**
69
+ * Relation between entities - inferred from foreign key constraints.
70
+ * Contains raw constraint data; plugins derive names as needed.
71
+ */
72
+ export interface Relation {
73
+ /** Relationship kind */
74
+ readonly kind: "hasMany" | "hasOne" | "belongsTo";
75
+ /** Target entity name (not table name) */
76
+ readonly targetEntity: string;
77
+ /** Original FK constraint name */
78
+ readonly constraintName: string;
79
+ /** Column mappings (supports composite FKs) */
80
+ readonly columns: readonly {
81
+ readonly local: string;
82
+ readonly foreign: string;
83
+ }[];
84
+ /** Smart tags from constraint comment */
85
+ readonly tags: SmartTags;
86
+ }
87
+ /**
88
+ * Primary key information
89
+ */
90
+ export interface PrimaryKey {
91
+ /** Column names in the primary key */
92
+ readonly columns: readonly string[];
93
+ /** True if from @primaryKey tag, false if real PK constraint */
94
+ readonly isVirtual: boolean;
95
+ }
96
+ /**
97
+ * Index method types
98
+ */
99
+ export type IndexMethod = "btree" | "gin" | "gist" | "hash" | "brin" | "spgist";
100
+ /**
101
+ * Function volatility classification - affects query optimization and caching
102
+ */
103
+ export type Volatility = "immutable" | "stable" | "volatile";
104
+ /**
105
+ * Information about a database index
106
+ */
107
+ export interface IndexDef {
108
+ /** PostgreSQL index name */
109
+ readonly name: string;
110
+ /** Inflected column names (camelCase) */
111
+ readonly columns: readonly string[];
112
+ /** Original PostgreSQL column names */
113
+ readonly columnNames: readonly string[];
114
+ /** True if this is a unique index */
115
+ readonly isUnique: boolean;
116
+ /** True if this is a primary key index */
117
+ readonly isPrimary: boolean;
118
+ /** True if this is a partial index (has WHERE clause) */
119
+ readonly isPartial: boolean;
120
+ /** WHERE clause for partial indexes (raw SQL) */
121
+ readonly predicate?: string;
122
+ /** Index method (btree, gin, gist, hash, brin, spgist) */
123
+ readonly method: IndexMethod;
124
+ /** True if any "column" is actually an expression (not a real column) */
125
+ readonly hasExpressions: boolean;
126
+ /** Operator class names for each indexed column (e.g., "gin_trgm_ops", "tsvector_ops") */
127
+ readonly opclassNames: readonly string[];
128
+ }
129
+ /**
130
+ * Permissions for a field (column) based on connected role's ACLs
131
+ */
132
+ export interface FieldPermissions {
133
+ /** Column can be selected */
134
+ readonly canSelect: boolean;
135
+ /** Column can be used in INSERT */
136
+ readonly canInsert: boolean;
137
+ /** Column can be used in UPDATE */
138
+ readonly canUpdate: boolean;
139
+ }
140
+ /**
141
+ * Permissions for an entity (table/view) based on connected role's ACLs
142
+ */
143
+ export interface EntityPermissions {
144
+ /** Table can be selected from */
145
+ readonly canSelect: boolean;
146
+ /** Rows can be inserted */
147
+ readonly canInsert: boolean;
148
+ /** Rows can be updated */
149
+ readonly canUpdate: boolean;
150
+ /** Rows can be deleted */
151
+ readonly canDelete: boolean;
152
+ }
153
+ /**
154
+ * All possible entity kinds
155
+ */
156
+ export type EntityKind = "table" | "view" | "enum" | "domain" | "composite" | "function";
157
+ /**
158
+ * Base fields shared by all entity kinds
159
+ */
160
+ interface EntityBase {
161
+ /** Inflected entity name (PascalCase) */
162
+ readonly name: string;
163
+ /** Original PostgreSQL object name (table, view, or type name) */
164
+ readonly pgName: string;
165
+ /** PostgreSQL schema name */
166
+ readonly schemaName: string;
167
+ /** Smart tags from comment */
168
+ readonly tags: SmartTags;
169
+ }
170
+ /**
171
+ * A table or view entity - has shapes, relations, and permissions
172
+ */
173
+ export interface TableEntity extends EntityBase {
174
+ /** Entity kind discriminator */
175
+ readonly kind: "table" | "view";
176
+ /** Raw class from pg-introspection */
177
+ readonly pgClass: PgClass;
178
+ /** Primary key (may be undefined for views without @primaryKey) */
179
+ readonly primaryKey?: PrimaryKey;
180
+ /** Indexes on this entity */
181
+ readonly indexes: readonly IndexDef[];
182
+ /** Shapes for this entity */
183
+ readonly shapes: {
184
+ /** Base shape (row) - always present */
185
+ readonly row: Shape;
186
+ /** Insert shape - only if different from base */
187
+ readonly insert?: Shape;
188
+ /** Update shape - only if different from insert (or base) */
189
+ readonly update?: Shape;
190
+ };
191
+ /** Relations to other entities */
192
+ readonly relations: readonly Relation[];
193
+ /** Permissions for the connected role */
194
+ readonly permissions: EntityPermissions;
195
+ }
196
+ /**
197
+ * An enum entity - represents a PostgreSQL enum type
198
+ */
199
+ export interface EnumEntity extends EntityBase {
200
+ /** Entity kind discriminator */
201
+ readonly kind: "enum";
202
+ /** Raw type from pg-introspection */
203
+ readonly pgType: PgType;
204
+ /** Enum values in order */
205
+ readonly values: readonly string[];
206
+ }
207
+ /**
208
+ * A CHECK constraint on a domain type
209
+ */
210
+ export interface DomainConstraint {
211
+ /** Constraint name */
212
+ readonly name: string;
213
+ /** Raw constraint expression (from pg_constraint.conbin decompiled) */
214
+ readonly expression?: string;
215
+ }
216
+ /**
217
+ * A domain entity - represents a PostgreSQL domain type (constrained wrapper over a base type)
218
+ */
219
+ export interface DomainEntity extends EntityBase {
220
+ /** Entity kind discriminator */
221
+ readonly kind: "domain";
222
+ /** Raw type from pg-introspection */
223
+ readonly pgType: PgType;
224
+ /** Name of the underlying base type (e.g., "citext", "text") */
225
+ readonly baseTypeName: string;
226
+ /** OID of the base type (for type mapping) */
227
+ readonly baseTypeOid: number;
228
+ /** Whether the domain has a NOT NULL constraint */
229
+ readonly notNull: boolean;
230
+ /** Domain CHECK constraints */
231
+ readonly constraints: readonly DomainConstraint[];
232
+ }
233
+ /**
234
+ * A composite entity - represents a user-defined PostgreSQL composite type
235
+ *
236
+ * Note: Table row types (auto-generated composites with typrelid != 0) are NOT included.
237
+ * Only explicitly created composite types are represented here.
238
+ */
239
+ export interface CompositeEntity extends EntityBase {
240
+ /** Entity kind discriminator */
241
+ readonly kind: "composite";
242
+ /** Raw type from pg-introspection */
243
+ readonly pgType: PgType;
244
+ /** Fields in the composite type (reuses Field interface) */
245
+ readonly fields: readonly Field[];
246
+ }
247
+ export interface FunctionArg {
248
+ readonly name: string;
249
+ readonly typeName: string;
250
+ readonly hasDefault: boolean;
251
+ }
252
+ /**
253
+ * A function entity - represents a PostgreSQL stored function
254
+ *
255
+ * Note: Only supports normal functions with IN parameters.
256
+ * Functions with OUT/INOUT parameters or RETURNS TABLE are not supported.
257
+ */
258
+ export interface FunctionEntity extends EntityBase {
259
+ /** Entity kind discriminator */
260
+ readonly kind: "function";
261
+ /** Raw proc from pg-introspection */
262
+ readonly pgProc: PgProc;
263
+ /** Return type name (e.g., "text", "pg_catalog.int4") */
264
+ readonly returnTypeName: string;
265
+ /** True if function returns SETOF */
266
+ readonly returnsSet: boolean;
267
+ /** Number of arguments (for overload disambiguation) */
268
+ readonly argCount: number;
269
+ /** Function arguments */
270
+ readonly args: readonly FunctionArg[];
271
+ /** Volatility classification */
272
+ readonly volatility: Volatility;
273
+ /** True if function is STRICT (NULL input = NULL output) */
274
+ readonly isStrict: boolean;
275
+ /** Whether the current role can execute this function */
276
+ readonly canExecute: boolean;
277
+ /** True if function belongs to an installed extension */
278
+ readonly isFromExtension: boolean;
279
+ }
280
+ /**
281
+ * An entity represents a table, view, enum, domain, or composite type in the database.
282
+ *
283
+ * Use the `kind` discriminator to narrow the type:
284
+ * ```typescript
285
+ * if (entity.kind === "enum") {
286
+ * // entity is EnumEntity, has .values
287
+ * } else if (entity.kind === "domain") {
288
+ * // entity is DomainEntity, has .baseTypeName, .constraints
289
+ * } else if (entity.kind === "composite") {
290
+ * // entity is CompositeEntity, has .fields
291
+ * } else {
292
+ * // entity is TableEntity, has .shapes, .relations, etc.
293
+ * }
294
+ * ```
295
+ */
296
+ export type Entity = TableEntity | EnumEntity | DomainEntity | CompositeEntity | FunctionEntity;
297
+ /**
298
+ * Check if an entity is a table or view (has shapes, relations, etc.)
299
+ */
300
+ export declare function isTableEntity(entity: Entity): entity is TableEntity;
301
+ /**
302
+ * Check if an entity is an enum (has values)
303
+ */
304
+ export declare function isEnumEntity(entity: Entity): entity is EnumEntity;
305
+ /**
306
+ * Check if an entity is a domain (has baseTypeName, constraints)
307
+ */
308
+ export declare function isDomainEntity(entity: Entity): entity is DomainEntity;
309
+ /**
310
+ * Check if an entity is a composite type (has fields)
311
+ */
312
+ export declare function isCompositeEntity(entity: Entity): entity is CompositeEntity;
313
+ /**
314
+ * Check if an entity is a function (has args, volatility, etc.)
315
+ */
316
+ export declare function isFunctionEntity(entity: Entity): entity is FunctionEntity;
317
+ /**
318
+ * Capability key - colon-separated hierarchical namespace
319
+ * e.g., "types", "schemas", "schemas:zod", "queries:crud"
320
+ */
321
+ export type CapabilityKey = string;
322
+ /**
323
+ * Artifact - plugin output stored in IR for downstream plugins
324
+ */
325
+ export interface Artifact {
326
+ /** Capability this artifact provides */
327
+ readonly capability: CapabilityKey;
328
+ /** Plugin that created this artifact */
329
+ readonly plugin: string;
330
+ /** Plugin-specific data */
331
+ readonly data: unknown;
332
+ }
333
+ /**
334
+ * Information about a PostgreSQL extension
335
+ */
336
+ export interface ExtensionInfo {
337
+ /** Extension name (e.g., "citext", "postgis") */
338
+ readonly name: string;
339
+ /** Namespace OID where extension objects are installed */
340
+ readonly namespaceOid: string;
341
+ /** Extension version */
342
+ readonly version: string | null;
343
+ }
344
+ /**
345
+ * The complete Semantic IR
346
+ */
347
+ export interface SemanticIR {
348
+ /** All entities (tables, views, enums) keyed by name */
349
+ readonly entities: ReadonlyMap<string, Entity>;
350
+ /** Artifacts from plugins, keyed by capability */
351
+ readonly artifacts: ReadonlyMap<CapabilityKey, Artifact>;
352
+ /** Installed PostgreSQL extensions */
353
+ readonly extensions: readonly ExtensionInfo[];
354
+ /** When introspection was performed */
355
+ readonly introspectedAt: Date;
356
+ /** PostgreSQL schemas that were introspected */
357
+ readonly schemas: readonly string[];
358
+ }
359
+ /**
360
+ * Mutable builder for SemanticIR - used during IR construction
361
+ */
362
+ export interface SemanticIRBuilder {
363
+ entities: Map<string, Entity>;
364
+ artifacts: Map<CapabilityKey, Artifact>;
365
+ extensions: ExtensionInfo[];
366
+ introspectedAt: Date;
367
+ schemas: string[];
368
+ }
369
+ /**
370
+ * Create an empty IR builder
371
+ */
372
+ export declare function createIRBuilder(schemas: readonly string[]): SemanticIRBuilder;
373
+ /**
374
+ * Freeze a builder into an immutable IR
375
+ */
376
+ export declare function freezeIR(builder: SemanticIRBuilder): SemanticIR;
377
+ /**
378
+ * Get all table/view entities from the IR
379
+ */
380
+ export declare function getTableEntities(ir: SemanticIR): TableEntity[];
381
+ /**
382
+ * Get all enum entities from the IR
383
+ */
384
+ export declare function getEnumEntities(ir: SemanticIR): EnumEntity[];
385
+ /**
386
+ * Get all domain entities from the IR
387
+ */
388
+ export declare function getDomainEntities(ir: SemanticIR): DomainEntity[];
389
+ /**
390
+ * Get all composite entities from the IR
391
+ */
392
+ export declare function getCompositeEntities(ir: SemanticIR): CompositeEntity[];
393
+ /**
394
+ * Get all function entities from the IR
395
+ */
396
+ export declare function getFunctionEntities(ir: SemanticIR): FunctionEntity[];
397
+ /**
398
+ * A reversed relation - represents the "other side" of a belongsTo FK.
399
+ *
400
+ * If orders.user_id → users.id creates a "orders belongsTo users" relation,
401
+ * the reverse is "users hasMany orders".
402
+ */
403
+ export interface ReverseRelation {
404
+ /** The kind of reverse relationship */
405
+ readonly kind: "hasMany" | "hasOne";
406
+ /** Entity name that has the FK (the "child" table) */
407
+ readonly sourceEntity: string;
408
+ /** Original constraint name */
409
+ readonly constraintName: string;
410
+ /** Column mappings (same as original, but semantically reversed) */
411
+ readonly columns: readonly {
412
+ /** Column on the target (this) entity - the referenced column */
413
+ readonly local: string;
414
+ /** Column on the source entity - the FK column */
415
+ readonly foreign: string;
416
+ }[];
417
+ /** Original relation this was derived from */
418
+ readonly originalRelation: Relation;
419
+ }
420
+ /**
421
+ * Get all reverse relations pointing TO this entity.
422
+ *
423
+ * Scans all entities for belongsTo relations targeting the given entity
424
+ * and returns them as hasMany relations.
425
+ *
426
+ * @example
427
+ * ```typescript
428
+ * // If orders.user_id → users.id exists as "orders belongsTo users"
429
+ * const reverseRels = getReverseRelations(ir, "User")
430
+ * // Returns: [{ kind: "hasMany", sourceEntity: "Order", ... }]
431
+ * ```
432
+ */
433
+ export declare function getReverseRelations(ir: SemanticIR, entityName: string): readonly ReverseRelation[];
434
+ /**
435
+ * Get all relations for an entity in both directions.
436
+ *
437
+ * Combines the entity's direct relations (belongsTo) with reverse relations
438
+ * (hasMany) from other entities pointing to this one.
439
+ */
440
+ export interface AllRelations {
441
+ /** Direct relations from this entity (belongsTo) */
442
+ readonly belongsTo: readonly Relation[];
443
+ /** Reverse relations to this entity (hasMany) */
444
+ readonly hasMany: readonly ReverseRelation[];
445
+ }
446
+ export declare function getAllRelations(ir: SemanticIR, entityName: string): AllRelations | undefined;
447
+ export {};
448
+ //# sourceMappingURL=semantic-ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-ir.d.ts","sourceRoot":"","sources":["../../src/ir/semantic-ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ // ============================================================================
2
+ // Type Guards
3
+ // ============================================================================
4
+ /**
5
+ * Check if an entity is a table or view (has shapes, relations, etc.)
6
+ */
7
+ export function isTableEntity(entity) {
8
+ return entity.kind === "table" || entity.kind === "view";
9
+ }
10
+ /**
11
+ * Check if an entity is an enum (has values)
12
+ */
13
+ export function isEnumEntity(entity) {
14
+ return entity.kind === "enum";
15
+ }
16
+ /**
17
+ * Check if an entity is a domain (has baseTypeName, constraints)
18
+ */
19
+ export function isDomainEntity(entity) {
20
+ return entity.kind === "domain";
21
+ }
22
+ /**
23
+ * Check if an entity is a composite type (has fields)
24
+ */
25
+ export function isCompositeEntity(entity) {
26
+ return entity.kind === "composite";
27
+ }
28
+ /**
29
+ * Check if an entity is a function (has args, volatility, etc.)
30
+ */
31
+ export function isFunctionEntity(entity) {
32
+ return entity.kind === "function";
33
+ }
34
+ /**
35
+ * Create an empty IR builder
36
+ */
37
+ export function createIRBuilder(schemas) {
38
+ return {
39
+ entities: new Map(),
40
+ artifacts: new Map(),
41
+ extensions: [],
42
+ introspectedAt: new Date(),
43
+ schemas: [...schemas],
44
+ };
45
+ }
46
+ /**
47
+ * Freeze a builder into an immutable IR
48
+ */
49
+ export function freezeIR(builder) {
50
+ return {
51
+ entities: new Map(builder.entities),
52
+ artifacts: new Map(builder.artifacts),
53
+ extensions: [...builder.extensions],
54
+ introspectedAt: builder.introspectedAt,
55
+ schemas: [...builder.schemas],
56
+ };
57
+ }
58
+ // ============================================================================
59
+ // Helper Functions
60
+ // ============================================================================
61
+ /**
62
+ * Get all table/view entities from the IR
63
+ */
64
+ export function getTableEntities(ir) {
65
+ return [...ir.entities.values()].filter(isTableEntity);
66
+ }
67
+ /**
68
+ * Get all enum entities from the IR
69
+ */
70
+ export function getEnumEntities(ir) {
71
+ return [...ir.entities.values()].filter(isEnumEntity);
72
+ }
73
+ /**
74
+ * Get all domain entities from the IR
75
+ */
76
+ export function getDomainEntities(ir) {
77
+ return [...ir.entities.values()].filter(isDomainEntity);
78
+ }
79
+ /**
80
+ * Get all composite entities from the IR
81
+ */
82
+ export function getCompositeEntities(ir) {
83
+ return [...ir.entities.values()].filter(isCompositeEntity);
84
+ }
85
+ /**
86
+ * Get all function entities from the IR
87
+ */
88
+ export function getFunctionEntities(ir) {
89
+ return [...ir.entities.values()].filter(isFunctionEntity);
90
+ }
91
+ /**
92
+ * Get all reverse relations pointing TO this entity.
93
+ *
94
+ * Scans all entities for belongsTo relations targeting the given entity
95
+ * and returns them as hasMany relations.
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * // If orders.user_id → users.id exists as "orders belongsTo users"
100
+ * const reverseRels = getReverseRelations(ir, "User")
101
+ * // Returns: [{ kind: "hasMany", sourceEntity: "Order", ... }]
102
+ * ```
103
+ */
104
+ export function getReverseRelations(ir, entityName) {
105
+ const results = [];
106
+ for (const entity of ir.entities.values()) {
107
+ if (!isTableEntity(entity))
108
+ continue;
109
+ for (const relation of entity.relations) {
110
+ if (relation.targetEntity === entityName && relation.kind === "belongsTo") {
111
+ results.push({
112
+ // Default to hasMany; could be hasOne if unique constraint on FK
113
+ // TODO: detect unique constraint on FK columns for hasOne
114
+ kind: "hasMany",
115
+ sourceEntity: entity.name,
116
+ constraintName: relation.constraintName,
117
+ // Swap local/foreign perspective
118
+ columns: relation.columns.map((col) => ({
119
+ local: col.foreign, // Referenced column becomes "local"
120
+ foreign: col.local, // FK column becomes "foreign"
121
+ })),
122
+ originalRelation: relation,
123
+ });
124
+ }
125
+ }
126
+ }
127
+ return results;
128
+ }
129
+ export function getAllRelations(ir, entityName) {
130
+ const entity = ir.entities.get(entityName);
131
+ if (!entity || !isTableEntity(entity))
132
+ return undefined;
133
+ return {
134
+ belongsTo: entity.relations.filter((r) => r.kind === "belongsTo"),
135
+ hasMany: getReverseRelations(ir, entityName),
136
+ };
137
+ }
138
+ //# sourceMappingURL=semantic-ir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-ir.js","sourceRoot":"","sources":["../../src/ir/semantic-ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Smart Tags - configuration extracted from PostgreSQL COMMENT ON statements
3
+ */
4
+ import { Schema as S } from "effect";
5
+ /**
6
+ * Shape kinds for omit filtering
7
+ */
8
+ export declare const ShapeKind: S.Literal<["row", "insert", "update"]>;
9
+ export type ShapeKind = S.Schema.Type<typeof ShapeKind>;
10
+ /**
11
+ * Smart tags schema - extracted from pg_description comments
12
+ * Format: {"sourcerer": {...}} in the comment text
13
+ */
14
+ export declare const SmartTags: S.extend<S.Struct<{
15
+ name: S.optional<typeof S.String>;
16
+ omit: S.optional<S.Union<[typeof S.Boolean, S.Array$<S.Literal<["row", "insert", "update"]>>]>>;
17
+ type: S.optional<typeof S.String>;
18
+ deprecated: S.optional<S.Union<[typeof S.Boolean, typeof S.String]>>;
19
+ primaryKey: S.optional<S.Array$<typeof S.String>>;
20
+ fieldName: S.optional<typeof S.String>;
21
+ foreignFieldName: S.optional<typeof S.String>;
22
+ }>, S.Record$<typeof S.String, typeof S.Unknown>>;
23
+ export type SmartTags = S.Schema.Type<typeof SmartTags>;
24
+ //# sourceMappingURL=smart-tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-tags.d.ts","sourceRoot":"","sources":["../../src/ir/smart-tags.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEpC;;GAEG;AACH,eAAO,MAAM,SAAS,wCAAuC,CAAA;AAC7D,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;;iDAwBrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Smart Tags - configuration extracted from PostgreSQL COMMENT ON statements
3
+ */
4
+ import { Schema as S } from "effect";
5
+ /**
6
+ * Shape kinds for omit filtering
7
+ */
8
+ export const ShapeKind = S.Literal("row", "insert", "update");
9
+ /**
10
+ * Smart tags schema - extracted from pg_description comments
11
+ * Format: {"sourcerer": {...}} in the comment text
12
+ */
13
+ export const SmartTags = S.Struct({
14
+ // Renaming
15
+ name: S.optional(S.String),
16
+ // Omission: true = omit entirely, array = omit from specific shapes
17
+ omit: S.optional(S.Union(S.Boolean, S.Array(ShapeKind))),
18
+ // Type override (emitter-specific, passed through as string)
19
+ type: S.optional(S.String),
20
+ // Deprecation: true = deprecated, string = deprecated with message
21
+ deprecated: S.optional(S.Union(S.Boolean, S.String)),
22
+ // For views: define virtual primary key
23
+ primaryKey: S.optional(S.Array(S.String)),
24
+ // For constraints: relation naming
25
+ fieldName: S.optional(S.String),
26
+ foreignFieldName: S.optional(S.String),
27
+ }).pipe(
28
+ // Extension point: plugins can define additional keys
29
+ S.extend(S.Record({ key: S.String, value: S.Unknown })));
30
+ //# sourceMappingURL=smart-tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-tags.js","sourceRoot":"","sources":["../../src/ir/smart-tags.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAG7D;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,WAAW;IACX,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAE1B,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,QAAQ,CACd,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CACvC;IAED,6DAA6D;IAC7D,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAE1B,mEAAmE;IACnE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAEpD,wCAAwC;IACxC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAEzC,mCAAmC;IACnC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/B,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;CACvC,CAAC,CAAC,IAAI;AACL,sDAAsD;AACtD,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CACxD,CAAA"}