@rebasepro/server-postgres 0.22.0 → 0.24.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 (123) hide show
  1. package/dist/{BranchService-CucnFcSE.js → BranchService-BRt78gfa.js} +35 -18
  2. package/dist/BranchService-BRt78gfa.js.map +1 -0
  3. package/dist/PostgresBackendDriver.d.ts +116 -4
  4. package/dist/auth/services.d.ts +99 -22
  5. package/dist/{auth-users-columns-D2LBFrMH.js → auth-users-columns-C72EMoDJ.js} +17 -1
  6. package/dist/{auth-users-columns-D2LBFrMH.js.map → auth-users-columns-C72EMoDJ.js.map} +1 -1
  7. package/dist/backup/backup-cli.d.ts +22 -0
  8. package/dist/{backup-cli-DqBakiMO.js → backup-cli-DW5p9_zv.js} +17 -14
  9. package/dist/backup-cli-DW5p9_zv.js.map +1 -0
  10. package/dist/{backup-service-CaMOS76G.js → backup-service-EwcDVG-8.js} +7 -9
  11. package/dist/{backup-service-CaMOS76G.js.map → backup-service-EwcDVG-8.js.map} +1 -1
  12. package/dist/{cli-errors-Dka89exj.js → cli-errors-DsA-K9uP.js} +101 -1
  13. package/dist/cli-errors-DsA-K9uP.js.map +1 -0
  14. package/dist/cli-errors.d.ts +42 -0
  15. package/dist/cli-flags-BglvpjHv.js +138 -0
  16. package/dist/cli-flags-BglvpjHv.js.map +1 -0
  17. package/dist/cli-flags.d.ts +28 -0
  18. package/dist/cli-helpers.d.ts +18 -12
  19. package/dist/cli-scratch-database.d.ts +34 -0
  20. package/dist/cli.js +177 -287
  21. package/dist/cli.js.map +1 -1
  22. package/dist/{column-plan-helpers-CpILzHJS.js → column-plan-helpers-1-LQD0yI.js} +44 -38
  23. package/dist/column-plan-helpers-1-LQD0yI.js.map +1 -0
  24. package/dist/data-transformer.d.ts +0 -8
  25. package/dist/{doctor-CU9IogdL.js → doctor-C-sYWbmt.js} +228 -46
  26. package/dist/doctor-C-sYWbmt.js.map +1 -0
  27. package/dist/{ensure-collection-policies-Dzd-2S81.js → ensure-collection-policies-B1ureSIV.js} +73 -18
  28. package/dist/ensure-collection-policies-B1ureSIV.js.map +1 -0
  29. package/dist/{ensure-collection-tables-CpAgy51F.js → ensure-collection-tables-kkkHk8oo.js} +124 -37
  30. package/dist/ensure-collection-tables-kkkHk8oo.js.map +1 -0
  31. package/dist/{ensure-tables-Cr5B4UmH.js → ensure-tables-BmI_tRxc.js} +10 -3
  32. package/dist/ensure-tables-BmI_tRxc.js.map +1 -0
  33. package/dist/{generate-drizzle-schema-B537GIvz.js → generate-drizzle-schema-93M0lUxK.js} +2 -2
  34. package/dist/{generate-drizzle-schema-B537GIvz.js.map → generate-drizzle-schema-93M0lUxK.js.map} +1 -1
  35. package/dist/{generate-drizzle-schema-logic-BcMl7VSy.js → generate-drizzle-schema-logic-sSFDp6LR.js} +26 -8
  36. package/dist/generate-drizzle-schema-logic-sSFDp6LR.js.map +1 -0
  37. package/dist/generate-postgres-ddl-logic-BJsLaVNX.js +152 -0
  38. package/dist/generate-postgres-ddl-logic-BJsLaVNX.js.map +1 -0
  39. package/dist/generated-sql.d.ts +28 -0
  40. package/dist/index.es.js +4768 -1117
  41. package/dist/index.es.js.map +1 -1
  42. package/dist/{introspect-db-logic-C6LQdTxj.js → introspect-db-logic-kCETE8TY.js} +532 -39
  43. package/dist/introspect-db-logic-kCETE8TY.js.map +1 -0
  44. package/dist/introspect-db-queries-C_Q5VgQw.js +317 -0
  45. package/dist/introspect-db-queries-C_Q5VgQw.js.map +1 -0
  46. package/dist/{plan-schema-CboAIwLN.js → plan-schema-DU9exq6C.js} +291 -529
  47. package/dist/plan-schema-DU9exq6C.js.map +1 -0
  48. package/dist/{policy-drift-xJfy9xG7.js → policy-drift-B-J2hhm0.js} +3 -3
  49. package/dist/policy-drift-B-J2hhm0.js.map +1 -0
  50. package/dist/{generate-postgres-ddl-logic-D7imhYV8.js → render-ddl-Ds2t_d9V.js} +11 -149
  51. package/dist/render-ddl-Ds2t_d9V.js.map +1 -0
  52. package/dist/{rls-bootstrap-sql-H3rCFi3F.js → rls-bootstrap-sql-_KNnjanK.js} +562 -35
  53. package/dist/rls-bootstrap-sql-_KNnjanK.js.map +1 -0
  54. package/dist/{rls-enforcement-C6Xk0lA6.js → rls-enforcement-CfXOJJaW.js} +10 -2
  55. package/dist/rls-enforcement-CfXOJJaW.js.map +1 -0
  56. package/dist/schema/atlas-argv.d.ts +15 -0
  57. package/dist/schema/auth-schema.d.ts +170 -0
  58. package/dist/schema/classify-change.d.ts +29 -1
  59. package/dist/schema/column-plan-helpers.d.ts +51 -20
  60. package/dist/schema/destructive-sql.d.ts +71 -1
  61. package/dist/schema/doctor-cli.js +4 -4
  62. package/dist/schema/doctor.d.ts +34 -1
  63. package/dist/schema/ensure-collection-policies.d.ts +22 -0
  64. package/dist/schema/generate-drizzle-schema.js +1 -1
  65. package/dist/schema/generate-postgres-ddl-logic.d.ts +5 -5
  66. package/dist/schema/generate-postgres-ddl.js +1 -1
  67. package/dist/schema/generate-schema-commit.d.ts +12 -0
  68. package/dist/schema/introspect-db-logic.d.ts +31 -0
  69. package/dist/schema/introspect-db-queries.d.ts +1 -1
  70. package/dist/schema/introspect-db-search.d.ts +22 -0
  71. package/dist/schema/introspect-db-storage.d.ts +83 -0
  72. package/dist/schema/introspect-db.js +15 -314
  73. package/dist/schema/introspect-db.js.map +1 -1
  74. package/dist/schema/plan/diff-plan.d.ts +4 -3
  75. package/dist/schema/plan/plan-schema.d.ts +26 -11
  76. package/dist/schema/plan/render-ddl.d.ts +6 -0
  77. package/dist/schema/plan/types.d.ts +43 -12
  78. package/dist/search-column-BM-GV6vH.js +442 -0
  79. package/dist/search-column-BM-GV6vH.js.map +1 -0
  80. package/dist/security/policy-drift.d.ts +1 -1
  81. package/dist/security/rls-enforcement.d.ts +7 -0
  82. package/dist/services/BranchService.d.ts +22 -1
  83. package/dist/services/FetchService.d.ts +102 -32
  84. package/dist/services/PersistService.d.ts +41 -5
  85. package/dist/services/RelationService.d.ts +29 -0
  86. package/dist/services/RelationWriteService.d.ts +6 -0
  87. package/dist/services/cdc/CdcListener.d.ts +15 -5
  88. package/dist/services/cdc/identity-columns.d.ts +19 -0
  89. package/dist/services/cdc/trigger-cdc.d.ts +45 -7
  90. package/dist/services/channel-bus/PostgresChannelBus.d.ts +12 -7
  91. package/dist/services/channel-history.d.ts +17 -1
  92. package/dist/services/collection-helpers.d.ts +21 -0
  93. package/dist/services/dataService.d.ts +3 -20
  94. package/dist/services/field-op-sql.d.ts +71 -0
  95. package/dist/services/junction-writes.d.ts +19 -3
  96. package/dist/services/pg-notify-listener.d.ts +95 -6
  97. package/dist/services/read-field-access.d.ts +19 -0
  98. package/dist/services/realtimeService.d.ts +232 -44
  99. package/dist/services/row-pipeline.d.ts +5 -0
  100. package/dist/services/socket-liveness.d.ts +45 -0
  101. package/dist/services/soft-delete.d.ts +12 -2
  102. package/dist/services/sql-script.d.ts +71 -0
  103. package/dist/services/write-depth.d.ts +16 -0
  104. package/dist/services/write-transaction-scope.d.ts +42 -0
  105. package/dist/utils/drizzle-conditions.d.ts +49 -4
  106. package/dist/utils/sql-redaction.d.ts +21 -0
  107. package/dist/websocket.d.ts +57 -18
  108. package/package.json +9 -9
  109. package/dist/BranchService-CucnFcSE.js.map +0 -1
  110. package/dist/backup-cli-DqBakiMO.js.map +0 -1
  111. package/dist/cli-errors-Dka89exj.js.map +0 -1
  112. package/dist/column-plan-helpers-CpILzHJS.js.map +0 -1
  113. package/dist/doctor-CU9IogdL.js.map +0 -1
  114. package/dist/ensure-collection-policies-Dzd-2S81.js.map +0 -1
  115. package/dist/ensure-collection-tables-CpAgy51F.js.map +0 -1
  116. package/dist/ensure-tables-Cr5B4UmH.js.map +0 -1
  117. package/dist/generate-drizzle-schema-logic-BcMl7VSy.js.map +0 -1
  118. package/dist/generate-postgres-ddl-logic-D7imhYV8.js.map +0 -1
  119. package/dist/introspect-db-logic-C6LQdTxj.js.map +0 -1
  120. package/dist/plan-schema-CboAIwLN.js.map +0 -1
  121. package/dist/policy-drift-xJfy9xG7.js.map +0 -1
  122. package/dist/rls-bootstrap-sql-H3rCFi3F.js.map +0 -1
  123. package/dist/rls-enforcement-C6Xk0lA6.js.map +0 -1
@@ -1,8 +1,9 @@
1
1
  import { CollectionConfig, Property } from "@rebasepro/types";
2
+ import type { PgType, TablePlan } from "./plan/types.js";
2
3
  export type IssueSeverity = "error" | "warning" | "info";
3
4
  export interface DoctorIssue {
4
5
  severity: IssueSeverity;
5
- category: "missing_table" | "missing_column" | "type_mismatch" | "missing_constraint" | "schema_stale" | "missing_enum" | "enum_value_mismatch" | "missing_foreign_key" | "sdk_stale" | "sdk_not_generated" | "sdk_ungeneratable";
6
+ category: "missing_table" | "missing_column" | "type_mismatch" | "missing_constraint" | "primary_key_mismatch" | "schema_stale" | "missing_enum" | "enum_value_mismatch" | "missing_foreign_key" | "orphaned_junction" | "sdk_stale" | "sdk_not_generated" | "sdk_ungeneratable";
6
7
  table?: string;
7
8
  column?: string;
8
9
  expected?: string;
@@ -84,6 +85,14 @@ export declare function getExpectedColumnType(prop: Property): string | null;
84
85
  export declare function loadCollections(collectionsPath: string): Promise<CollectionConfig[]>;
85
86
  export declare function checkCollectionsVsSchema(collections: CollectionConfig[], schemaFilePath: string): Promise<DoctorPhase>;
86
87
  export declare function checkCollectionsVsSdk(collections: CollectionConfig[], sdkFilePath: string): Promise<DoctorPhase>;
88
+ interface DbColumn {
89
+ table_schema: string;
90
+ table_name: string;
91
+ column_name: string;
92
+ data_type: string;
93
+ is_nullable: string;
94
+ udt_name: string;
95
+ }
87
96
  /**
88
97
  * Extensions the collections need, that the database does not have installed.
89
98
  *
@@ -115,6 +124,29 @@ export declare function schemaStampIssues(pool: {
115
124
  rows: T[];
116
125
  }>;
117
126
  }, collections: CollectionConfig[]): Promise<DoctorIssue[]>;
127
+ /**
128
+ * What to do about a column whose type is not the one the collection plans.
129
+ *
130
+ * Both ways out, because the doctor cannot know which side is right: the
131
+ * property moved, or the database did. Putting the property back always clears
132
+ * the finding; converting the column clears it when every value converts.
133
+ */
134
+ export declare function typeMismatchFix(schema: string, table: string, column: string, actual: string, planned: PgType | undefined): string;
135
+ /**
136
+ * The table's primary key against the one the collection reads it by.
137
+ *
138
+ * Rebase addresses a row by the key the plan names — the `isId` property, or
139
+ * the implicit `id` — so a table keyed on other columns, or on none, serves
140
+ * reads and writes against a key that does not hold. An error, because that is
141
+ * what it is at runtime.
142
+ */
143
+ export declare function primaryKeyIssues(tablePlan: TablePlan, dbPk: string[], displayName: string): DoctorIssue[];
144
+ /**
145
+ * A junction's two key columns: present, typed like the keys they point at,
146
+ * and the table keyed on the pair. Order is not compared — boot and `db push`
147
+ * have built the key in both orders, and either one serves the same rows.
148
+ */
149
+ export declare function junctionKeyIssues(junctionPlan: TablePlan, dbColumns: DbColumn[], dbPk: string[], displayName: string): DoctorIssue[];
118
150
  export declare function checkCollectionsVsDatabase(collections: CollectionConfig[], databaseUrl: string): Promise<DoctorPhase>;
119
151
  export declare function renderReport(report: DoctorReport): void;
120
152
  export declare function runDoctor(options: {
@@ -123,3 +155,4 @@ export declare function runDoctor(options: {
123
155
  sdkPath: string;
124
156
  databaseUrl?: string;
125
157
  }): Promise<DoctorReport>;
158
+ export {};
@@ -81,4 +81,26 @@ export interface PolicyEnsureResult {
81
81
  */
82
82
  orphansDropped: number;
83
83
  }
84
+ export interface TableLockResult {
85
+ /** Tables RLS is now on for. */
86
+ locked: number;
87
+ /** Tables it could not be switched on for. See {@link PolicyEnsureResult.unsecured}. */
88
+ unsecured: PolicyEnsureResult["unsecured"];
89
+ }
90
+ /**
91
+ * Switch RLS on for every table the collections declare — each collection's
92
+ * and each junction's — and do nothing else.
93
+ *
94
+ * The first thing `rebase db push` does once Atlas has committed. Atlas cannot
95
+ * carry `ENABLE ROW LEVEL SECURITY` (its free tier neither plans nor reads it),
96
+ * so a table it creates arrives with RLS off — while the user role already
97
+ * holds DML on it through the schema's default privileges. Everything push runs
98
+ * after Atlas can refuse: the vector, search and trigger DDL, the policies
99
+ * themselves. Locking first means none of those failures can leave a table
100
+ * open: RLS with no policy denies, which is a state a failed push may leave.
101
+ *
102
+ * A declared table that is not in the database is skipped — nothing can reach
103
+ * a table that does not exist, and the step that creates it locks it.
104
+ */
105
+ export declare function lockCollectionTables(client: Queryable, collections: CollectionConfig[]): Promise<TableLockResult>;
84
106
  export declare function ensureCollectionPolicies(client: Queryable, collections: CollectionConfig[], log?: (message: string) => void): Promise<PolicyEnsureResult>;
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  __createRequire(import.meta.url);
3
- import { t as main } from "../generate-drizzle-schema-B537GIvz.js";
3
+ import { t as main } from "../generate-drizzle-schema-93M0lUxK.js";
4
4
  //#region src/schema/bin/generate-drizzle-schema.ts
5
5
  /**
6
6
  * The built entry point for `generate-drizzle-schema`.
@@ -31,7 +31,7 @@ type ResolveCollection = (slug: string) => CollectionConfig | undefined;
31
31
  */
32
32
  export declare const generatePolicyStatements: (collection: CollectionConfig, rule: SecurityRule, resolveCollection: ResolveCollection) => string[];
33
33
  /**
34
- * `drizzle/schema.sql` — the desired state Atlas diffs the database against.
34
+ * `.rebase/sql/schema.sql` — the desired state Atlas diffs the database against.
35
35
  *
36
36
  * Synchronous. It was `async` with nothing to await, which made every caller
37
37
  * (the writer script, the doctor, the live editor, two gates) carry a promise
@@ -39,10 +39,10 @@ export declare const generatePolicyStatements: (collection: CollectionConfig, ru
39
39
  * `[object Promise]`.
40
40
  */
41
41
  export declare const generatePostgresDdl: (allCollections: CollectionConfig[], options?: DdlRenderOptions) => string;
42
- /** `drizzle/policies.sql` — the RLS policies. Atlas has no model for a policy. */
42
+ /** `.rebase/sql/policies.sql` — the RLS policies. Atlas has no model for a policy. */
43
43
  export declare const generatePostgresPoliciesDdl: (allCollections: CollectionConfig[]) => string;
44
44
  /**
45
- * `drizzle/search.sql` — everything a `search` block needs, as a file Rebase
45
+ * `.rebase/sql/search.sql` — everything a `search` block needs, as a file Rebase
46
46
  * applies itself.
47
47
  *
48
48
  * Search is one of the parts of the schema Atlas does not own, for two
@@ -70,7 +70,7 @@ export declare const generatePostgresSearchDdl: (allCollections: CollectionConfi
70
70
  */
71
71
  export declare const searchExcludePatterns: (allCollections: CollectionConfig[]) => string[];
72
72
  /**
73
- * `drizzle/vector.sql` — the `vector` columns, their ANN indexes and, when a
73
+ * `.rebase/sql/vector.sql` — the `vector` columns, their ANN indexes and, when a
74
74
  * database declared it, the extension.
75
75
  *
76
76
  * Vector is out of Atlas's hands for a narrower reason than search: not that
@@ -86,7 +86,7 @@ export declare const generatePostgresVectorDdl: (allCollections: CollectionConfi
86
86
  /** @see searchExcludePatterns */
87
87
  export declare const vectorExcludePatterns: (allCollections: CollectionConfig[]) => string[];
88
88
  /**
89
- * `drizzle/triggers.sql` — the `BEFORE UPDATE` triggers behind
89
+ * `.rebase/sql/triggers.sql` — the `BEFORE UPDATE` triggers behind
90
90
  * `autoValue: "on_update"`, and the one function they share.
91
91
  *
92
92
  * A trigger is a function plus a binding, so it is carved out of Atlas's view
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  __createRequire(import.meta.url);
3
- import { a as generatePostgresVectorDdl, i as generatePostgresTriggersDdl, n as generatePostgresPoliciesDdl, r as generatePostgresSearchDdl, t as generatePostgresDdl } from "../generate-postgres-ddl-logic-D7imhYV8.js";
3
+ import { a as generatePostgresVectorDdl, i as generatePostgresTriggersDdl, n as generatePostgresPoliciesDdl, r as generatePostgresSearchDdl, t as generatePostgresDdl } from "../generate-postgres-ddl-logic-BJsLaVNX.js";
4
4
  import { n as outError, t as out } from "../cli-output-CNdMql-L.js";
5
5
  import { loadCollectionsFromDirectory } from "@rebasepro/server";
6
6
  import { declaredDatabaseExtensions } from "@rebasepro/types";
@@ -72,6 +72,12 @@ export interface SchemaCommitInput {
72
72
  * a statement that applies and one that is rejected.
73
73
  */
74
74
  existing?: ExistingSchema;
75
+ /**
76
+ * Plan a commit of the source alone — "Edit source only". An unapplicable
77
+ * change is not refused: it is committed with no statements, under a
78
+ * message that names what the database keeps.
79
+ */
80
+ sourceOnly?: boolean;
75
81
  }
76
82
  export interface SchemaCommit {
77
83
  /** Every file the commit writes, source and generated alike. */
@@ -123,6 +129,12 @@ export declare class SchemaCommitError extends Error {
123
129
  * where there is no database to describe.
124
130
  */
125
131
  export declare function additiveStatements(before: CollectionConfig[], after: CollectionConfig[], existing?: ExistingSchema, options?: EnsureOptions): string[];
132
+ /**
133
+ * The commit of an "Edit source only": what changed in the source, and what
134
+ * the database keeps — `chore(schema): remove sku from products (source only —
135
+ * column products.sku kept)`. The body lists what each change leaves behind.
136
+ */
137
+ export declare function sourceOnlyCommitMessage(classified: ClassifiedChanges): string;
126
138
  /** A commit message that says what changed rather than that something did. */
127
139
  export declare function commitMessage(classified: ClassifiedChanges): string;
128
140
  /**
@@ -91,6 +91,24 @@ export interface SchemaMetadata {
91
91
  */
92
92
  rowCounts: Record<string, number>;
93
93
  }
94
+ /**
95
+ * Why a table keyed on several columns is not generated as a collection, or
96
+ * `undefined` when it is.
97
+ *
98
+ * Several `isId` properties are one composite key, and the planner builds that
99
+ * table under the same `PRIMARY KEY (a, b)` — so such a table round-trips when
100
+ * two things hold:
101
+ *
102
+ * - **Every key column can carry `isId`,** which exists on string and number
103
+ * properties only. Read from the column's SQL type, not a data sample: a
104
+ * `line_no` holding only 1s is not a boolean. A key with a column of another
105
+ * type — pagila's `payment` is keyed on a timestamp too — can be marked on
106
+ * some of its columns only, and those would be read as the whole key.
107
+ * - **Nothing points at it.** A foreign key into it, or a junction, is a link
108
+ * into a composite key, which the planner refuses: the relation has one
109
+ * column to point with.
110
+ */
111
+ export declare function compositeKeySkipReason(meta: TableMeta, allFks: ForeignKeyRow[]): string | undefined;
94
112
  export interface TableMeta {
95
113
  name: string;
96
114
  columns: TableColumn[];
@@ -232,6 +250,19 @@ export interface GenerationContext {
232
250
  * from the target project and passes it. See `detectCollectionBuilder`.
233
251
  */
234
252
  builder?: CollectionBuilder;
253
+ /**
254
+ * Collects one line per column the planner will not reproduce exactly —
255
+ * what `rebase db push` would do to it, and how to avoid that when there is
256
+ * a way. The CLI prints them; the same lines are written at the top of the
257
+ * generated file.
258
+ */
259
+ notes?: string[];
260
+ /**
261
+ * Tables this run does not generate a collection for, so nothing may point
262
+ * at them: a relation whose target file does not exist is an import that
263
+ * does not resolve.
264
+ */
265
+ skippedTables?: ReadonlySet<string>;
235
266
  }
236
267
  /**
237
268
  * Generate the full TypeScript file content for a single collection.
@@ -71,7 +71,7 @@ export declare const TABLES_QUERY = "\n SELECT c.relname AS table_name,\n
71
71
  * errors. `character_maximum_length` is the declared `varchar(n)` bound —
72
72
  * already enforced by the database, and free to surface as validation.
73
73
  */
74
- export declare const COLUMNS_QUERY = "\n SELECT\n c.table_name,\n c.column_name,\n c.data_type,\n c.udt_name,\n c.is_nullable,\n c.column_default,\n c.ordinal_position,\n c.is_generated,\n c.is_identity,\n c.identity_generation,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n (SELECT a.atttypmod FROM pg_attribute a\n JOIN pg_class pc ON a.attrelid = pc.oid\n WHERE pc.relname = c.table_name\n AND a.attname = c.column_name\n AND pc.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = c.table_schema)) as atttypmod\n FROM information_schema.columns c\n WHERE c.table_schema = $1\n ORDER BY c.table_name, c.ordinal_position\n";
74
+ export declare const COLUMNS_QUERY = "\n SELECT\n c.table_name,\n c.column_name,\n c.data_type,\n c.udt_name,\n c.is_nullable,\n c.column_default,\n c.ordinal_position,\n c.is_generated,\n c.generation_expression,\n c.is_identity,\n c.identity_generation,\n c.character_maximum_length,\n c.numeric_precision,\n c.numeric_scale,\n (SELECT a.atttypmod FROM pg_attribute a\n JOIN pg_class pc ON a.attrelid = pc.oid\n WHERE pc.relname = c.table_name\n AND a.attname = c.column_name\n AND pc.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = c.table_schema)) as atttypmod\n FROM information_schema.columns c\n WHERE c.table_schema = $1\n ORDER BY c.table_name, c.ordinal_position\n";
75
75
  export declare const ENUMS_QUERY = "\n SELECT t.typname AS enum_name,\n e.enumlabel AS enum_value,\n e.enumsortorder AS sort_order\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = $1\n ORDER BY t.typname, e.enumsortorder\n";
76
76
  /**
77
77
  * Primary key columns, in key order.
@@ -0,0 +1,22 @@
1
+ import type { TableColumn } from "./introspect-db-logic.js";
2
+ /** What introspection makes of a table's search columns. */
3
+ export interface ReconstructedSearch {
4
+ /** The generated columns that belong to the search block — never emitted as properties. */
5
+ columns: Set<string>;
6
+ /** The `search: { … }` source, when the stamp confirmed it. */
7
+ block?: string;
8
+ note?: string;
9
+ }
10
+ /**
11
+ * The search block a table's stamped generated columns were built from, or a
12
+ * note saying why it could not be read back.
13
+ */
14
+ export declare function reconstructSearchBlock(input: {
15
+ schema: string;
16
+ table: string;
17
+ columns: TableColumn[];
18
+ /** column → `COMMENT ON COLUMN`. */
19
+ comments: Map<string, string>;
20
+ /** column → the property key it is generated under. */
21
+ keyByColumn: Map<string, string>;
22
+ }): ReconstructedSearch;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The property keys a column needs for the planner to build that same column.
3
+ *
4
+ * Introspection writes collections, and `rebase db push` plans them back into
5
+ * DDL. The two used to read a column differently: introspection wrote
6
+ * `type: "number"` for an `integer`, and the planner reads an unqualified
7
+ * number as `NUMERIC`; `validation.max: 40` for a `varchar(40)`, and the
8
+ * planner reads an unqualified string as `TEXT`; a `time` as a plain `date`,
9
+ * which the planner makes a `timestamptz` — a change Postgres refuses to cast.
10
+ * So adopting a database — introspect, then push, the documented path — planned
11
+ * a type change on nearly every column, and some it could not even dry-run.
12
+ *
13
+ * Each function here answers one question about one column: what to write so
14
+ * that `planSchema` produces exactly what the catalogue holds. Where no
15
+ * property can say it, the answer is a note naming the column and what a push
16
+ * would do to it, so the reader decides before anything runs.
17
+ *
18
+ * Pure: catalogue rows in, keys and notes out.
19
+ */
20
+ import type { ForeignKeyRow, TableColumn } from "./introspect-db-logic.js";
21
+ /** Keys to write on a property, as `key: value` source fragments, plus what could not be said. */
22
+ export interface ColumnStorage {
23
+ /** e.g. `columnType: "varchar"`, `precision: 10`. */
24
+ keys: string[];
25
+ /** Why the planner will not reproduce this column exactly, when it will not. */
26
+ note?: string;
27
+ }
28
+ /**
29
+ * The name Postgres gives a `SERIAL` column's sequence — `ChooseRelationName`
30
+ * with the `seq` label: `<table>_<column>_seq`, and when that is over 63 bytes
31
+ * the longer of the two names is shortened, one character at a time, until it
32
+ * fits.
33
+ */
34
+ export declare function serialSequenceName(table: string, column: string): string;
35
+ /**
36
+ * The `isId` (and `columnType`) a single-column primary key needs.
37
+ *
38
+ * `isId: "increment"` is an identity column, and only an INTEGER one. A serial
39
+ * key — an integer with a `nextval` default — is `SERIAL`/`BIGSERIAL`, declared
40
+ * through `columnType` beside `isId: "manual"`. A uuid key is `"uuid"` only when
41
+ * the database generates it; a key with no default is `"manual"`, which keeps
42
+ * the planner from inventing one.
43
+ */
44
+ export declare function primaryKeyStorage(col: TableColumn, propType: string): ColumnStorage;
45
+ /**
46
+ * The keys a non-key column needs, for the property type introspection chose.
47
+ *
48
+ * `enumTypeName` is the type the planner would name for this column
49
+ * (`<table>_<column>`, cut to 63 bytes); an enum column whose type is called
50
+ * anything else cannot be declared, and the note says how to rename it.
51
+ */
52
+ export declare function columnStorage(col: TableColumn, propType: string, context: {
53
+ isEnumColumn: boolean;
54
+ enumTypeName: string;
55
+ enumTypeShared: boolean;
56
+ }): ColumnStorage;
57
+ /**
58
+ * The `columnType` an array column needs, or a note when its element type is
59
+ * not one the planner stores natively.
60
+ *
61
+ * Only `text[]`, `integer[]`, `boolean[]` and `numeric[]` are. Reading
62
+ * `bigint[]` as `integer[]` — what this used to do — planned a narrowing.
63
+ */
64
+ export declare function arrayStorage(col: TableColumn): {
65
+ columnType?: string;
66
+ innerType: string;
67
+ note?: string;
68
+ };
69
+ /**
70
+ * A column default as a `defaultValue`, when it is a literal a property can carry.
71
+ *
72
+ * `undefined` when there is no default to carry, or when the default is one the
73
+ * generator expresses another way (`now()` is `autoValue`, a key's default is
74
+ * its `isId`). `{ note }` when there is a default and no property can say it —
75
+ * a push would plan dropping it.
76
+ */
77
+ export declare function literalDefaultOf(col: TableColumn, propType: string): {
78
+ source: string;
79
+ } | {
80
+ note: string;
81
+ } | undefined;
82
+ /** `ON DELETE` as the relation's `onDelete`, when it is not the default the planner would choose. */
83
+ export declare function onDeleteOf(fk: ForeignKeyRow, required: boolean): string | undefined;