@rebasepro/server-postgres 0.17.1 → 0.17.2-canary.ga94217a

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 (35) hide show
  1. package/dist/{backup-service-BtgHxfFm.js → backup-service-DCk7KhhL.js} +3 -3
  2. package/dist/{backup-service-BtgHxfFm.js.map → backup-service-DCk7KhhL.js.map} +1 -1
  3. package/dist/cli-helpers.d.ts +26 -14
  4. package/dist/{collection-index-DxJBvVTH.js → collection-index-BRUg10H5.js} +2 -2
  5. package/dist/{collection-index-DxJBvVTH.js.map → collection-index-BRUg10H5.js.map} +1 -1
  6. package/dist/{ensure-collection-policies-BHk4TRuf.js → ensure-collection-policies-UCqgv_8c.js} +4 -4
  7. package/dist/{ensure-collection-policies-BHk4TRuf.js.map → ensure-collection-policies-UCqgv_8c.js.map} +1 -1
  8. package/dist/{ensure-collection-tables-DMjOkeRy.js → ensure-collection-tables-DgVixhX3.js} +256 -38
  9. package/dist/ensure-collection-tables-DgVixhX3.js.map +1 -0
  10. package/dist/index.es.js +12 -12
  11. package/dist/{rls-bootstrap-sql-DNzaWd4C.js → rls-bootstrap-sql-B5C9LoJ6.js} +2 -2
  12. package/dist/{rls-bootstrap-sql-DNzaWd4C.js.map → rls-bootstrap-sql-B5C9LoJ6.js.map} +1 -1
  13. package/dist/{rls-enforcement-C1RJ1uI2.js → rls-enforcement-DvAbL9YJ.js} +3 -3
  14. package/dist/{rls-enforcement-C1RJ1uI2.js.map → rls-enforcement-DvAbL9YJ.js.map} +1 -1
  15. package/dist/schema/atlas-argv.d.ts +58 -0
  16. package/dist/schema/carved-out-migration.d.ts +65 -0
  17. package/dist/schema/ensure-collection-tables.d.ts +13 -1
  18. package/dist/schema/generate-postgres-ddl-logic.d.ts +57 -5
  19. package/dist/schema/vector-index.d.ts +120 -0
  20. package/dist/{src-DiDgtX8P.js → src-DiB5RP2Z.js} +33 -3
  21. package/dist/{src-DiDgtX8P.js.map → src-DiB5RP2Z.js.map} +1 -1
  22. package/dist/{websocket-g1Ji7m4o.js → websocket-BZ4H5wUz.js} +19 -9
  23. package/dist/websocket-BZ4H5wUz.js.map +1 -0
  24. package/package.json +6 -6
  25. package/src/cli-helpers.ts +65 -34
  26. package/src/cli.ts +168 -71
  27. package/src/schema/atlas-argv.ts +94 -0
  28. package/src/schema/carved-out-migration.ts +404 -0
  29. package/src/schema/ensure-collection-tables.ts +59 -32
  30. package/src/schema/generate-postgres-ddl-logic.ts +147 -21
  31. package/src/schema/generate-postgres-ddl.ts +59 -6
  32. package/src/schema/generate-schema-commit.ts +31 -6
  33. package/src/schema/vector-index.ts +213 -0
  34. package/dist/ensure-collection-tables-DMjOkeRy.js.map +0 -1
  35. package/dist/websocket-g1Ji7m4o.js.map +0 -1
@@ -28,6 +28,17 @@
28
28
  * boot-time ensure render the *same* specification rather than describing the
29
29
  * same index twice, differently. `contracts/derived-names.txt` records the
30
30
  * names both produce, and CI fails if they diverge.
31
+ *
32
+ * ## And why the column itself is described here too
33
+ *
34
+ * `VECTOR(n)` is a type Atlas cannot be shown. It has to materialise the
35
+ * desired state in a dev database to diff against, that database is created
36
+ * empty and *emptied again* by Atlas at the start of every run, and nothing in
37
+ * the free tier can put `CREATE EXTENSION vector` back — so a `schema.sql`
38
+ * mentioning the type fails with `type "vector" does not exist` on every push,
39
+ * for good. Search hit the same wall for its own reasons and took the same way
40
+ * out: the objects leave `schema.sql`, Atlas is told to exclude them, and
41
+ * Rebase applies them itself. See `generatePostgresVectorDdl`.
31
42
  */
32
43
  import type { CollectionConfig, Property, VectorDistance } from "@rebasepro/types";
33
44
  /**
@@ -86,3 +97,112 @@ export declare const vectorIndexStatement: (spec: VectorIndexSpec) => string;
86
97
  export declare const vectorIndexStatements: (plan: VectorIndexPlan) => string[];
87
98
  /** The index names a plan creates — what the derived-names contract records. */
88
99
  export declare const vectorIndexNames: (plan: VectorIndexPlan) => string[];
100
+ /**
101
+ * The schema pgvector's types are installed into.
102
+ *
103
+ * `WITH SCHEMA public` for the same load-bearing reason `searchExtensionStatements`
104
+ * gives: an unqualified `CREATE EXTENSION` lands in the first schema on
105
+ * `search_path`, which is `"$user", public` — and the scaffold's role is named
106
+ * `rebase`, the same as a schema the generator creates. Left to itself the
107
+ * extension would install into `rebase`, and every unqualified `VECTOR(n)`
108
+ * below would fail to resolve.
109
+ */
110
+ export declare const VECTOR_EXTENSION_SCHEMA = "public";
111
+ /** The extension name a database has to name to let Rebase install pgvector. */
112
+ export declare const VECTOR_EXTENSION = "vector";
113
+ /**
114
+ * How a project says Rebase may install pgvector, quoted into the messages that
115
+ * have to name it. Spelled once so the option and the advice cannot drift.
116
+ */
117
+ export declare const VECTOR_EXTENSION_OPT_IN = "database({ extensions: [\"vector\"] })";
118
+ /** Did the project give Rebase leave to install pgvector? */
119
+ export declare const vectorExtensionDeclared: (extensions: readonly string[] | undefined) => boolean;
120
+ /**
121
+ * Install pgvector — emitted only when the database asked for it.
122
+ *
123
+ * Opt-in because installing an extension is a decision with a deployment behind
124
+ * it: the image has to ship the library, the role has to be allowed to install
125
+ * it, and a managed provider has to have it on an allow-list. None of that is
126
+ * visible from inside the connection, so Rebase does not decide it. See
127
+ * `DatabaseOptions.extensions`.
128
+ *
129
+ * Withholding the statement is not withholding the *column*: the column is
130
+ * still created, and Postgres refuses it with `type "vector" does not exist`
131
+ * on a database where pgvector was never installed by hand. That error is the
132
+ * one this design accepts, and `vectorExtensionHint` is what makes it name
133
+ * {@link VECTOR_EXTENSION_OPT_IN} rather than nothing.
134
+ */
135
+ export declare const vectorExtensionStatement: () => string;
136
+ /**
137
+ * The missing-pgvector explanation, appended to whichever error revealed it.
138
+ *
139
+ * Two readers, needing opposite things, which is why the branch is on the error
140
+ * text rather than on the configuration:
141
+ *
142
+ * - **`type "vector" does not exist`** — nobody opted in and the database has
143
+ * no pgvector. The fix is one line of config they cannot guess, so naming
144
+ * the option *is* the hint.
145
+ * - **the install itself failed** — the config is already right, and repeating
146
+ * the option would send them to edit a correct line. What is missing is the
147
+ * library on the server, or the grant.
148
+ *
149
+ * Lives here rather than beside either caller because both need it: the boot
150
+ * ensure raises the first through its action applier, and `rebase db push`
151
+ * raises it out of `applyVectorDdl`. A hint on only one path is how a bare
152
+ * `type "vector" does not exist` reaches somebody — which is the thing this
153
+ * exists to prevent.
154
+ */
155
+ export declare const vectorExtensionHint: (message: string) => string;
156
+ /** One `{ type: "vector" }` property, as a column. */
157
+ export interface VectorColumnSpec {
158
+ schema: string;
159
+ table: string;
160
+ column: string;
161
+ dimensions: number;
162
+ /** Rendered after the type, in the generator's order: UNIQUE then NOT NULL. */
163
+ modifiers: string;
164
+ }
165
+ /**
166
+ * Every vector column a collection declares.
167
+ *
168
+ * Wider than {@link buildVectorIndexPlan} on purpose: that one answers "what
169
+ * gets an ANN index", and skips both a property with `index: false` and one too
170
+ * wide to index. Either still needs its column.
171
+ */
172
+ export declare const buildVectorColumnSpecs: (collection: CollectionConfig, resolveColumn: (propName: string, prop?: Property | null) => string) => VectorColumnSpec[];
173
+ /** The column type — the one place `VECTOR(n)` is spelled. */
174
+ export declare const vectorColumnType: (spec: Pick<VectorColumnSpec, "dimensions">) => string;
175
+ /** The column definition as it appears inside `CREATE TABLE`. */
176
+ export declare const vectorColumnDefinition: (spec: VectorColumnSpec) => string;
177
+ /**
178
+ * Refuse — or perform — a `dimensions` change that `ADD COLUMN IF NOT EXISTS`
179
+ * would otherwise swallow.
180
+ *
181
+ * Without this the file *launders* the change: the ADD is a no-op against a
182
+ * column that exists, so a project that went from 384 to 768 dimensions would
183
+ * push clean, keep a 384-wide column, and fail on the next insert with a
184
+ * message about the row rather than about the config. Atlas used to catch this
185
+ * — it owned the column and planned the `ALTER … TYPE` — and taking the column
186
+ * out of its sight is exactly what makes the guard necessary.
187
+ *
188
+ * The widening is performed when the column holds no values, because that is
189
+ * the case Atlas handled and it is the common one: a developer changing
190
+ * embedding models before there are any embeddings. With values present the
191
+ * conversion is pgvector's to reject — every stored vector is the old width —
192
+ * so this refuses first and names the statement to run afterwards.
193
+ *
194
+ * `atttypmod` on a `vector` column *is* the dimension count: pgvector stores it
195
+ * directly rather than offsetting it the way `varchar` does. `-1` means the
196
+ * column was declared as a bare `vector`, which is drift in the same sense.
197
+ */
198
+ export declare const vectorDimensionGuard: (spec: VectorColumnSpec) => string;
199
+ /**
200
+ * The object names a collection's vector properties own, unqualified.
201
+ *
202
+ * What Atlas has to be told to exclude. Only the column and the ANN indexes: a
203
+ * `UNIQUE` or `NOT NULL` on the column is a property *of* the column, and
204
+ * excluding the column takes them with it — measured against Atlas 1.2.3 and
205
+ * 1.3.2, where a target carrying `vector(3) NOT NULL UNIQUE` and a `schema.sql`
206
+ * carrying neither reported "Schema is synced, no changes to be made".
207
+ */
208
+ export declare const vectorObjectNames: (collection: CollectionConfig, resolveColumn: (propName: string, prop?: Property | null) => string) => string[];
@@ -430,6 +430,11 @@ function registerResourceKind(spec) {
430
430
  if (existing && JSON.stringify(existing) !== JSON.stringify(spec)) throw new Error(`Resource kind "${spec.kind}" is already registered with a different definition. Two packages cannot define the same kind.`);
431
431
  registry().kinds.set(spec.kind, spec);
432
432
  }
433
+ /** Every declared resource, in declaration order, optionally filtered by kind. */
434
+ function declaredResources(kind) {
435
+ const all = [...registry().declarations.values()];
436
+ return kind ? all.filter((r) => r.kind === kind) : all;
437
+ }
433
438
  //#endregion
434
439
  //#region ../types/src/types/resource_kinds.ts
435
440
  /**
@@ -459,9 +464,34 @@ registerResourceKind({
459
464
  "REBASE_DRIVER",
460
465
  "REBASE_DB_POOL_MAX"
461
466
  ],
462
- optionKeys: ["databaseId", "migrations"],
467
+ optionKeys: [
468
+ "databaseId",
469
+ "migrations",
470
+ "extensions"
471
+ ],
463
472
  implicitDefault: true
464
473
  });
474
+ /**
475
+ * The extensions the project's databases gave Rebase leave to install.
476
+ *
477
+ * A flat union rather than a per-database answer, because the surfaces that ask
478
+ * — `rebase db push` and the boot schema-ensure — drive one connection and
479
+ * generate one `schema.sql` for every collection regardless of `dataSource`.
480
+ * Splitting the permission by data source would be a distinction the rest of
481
+ * that pipeline does not make, and a false precision is worse than none.
482
+ *
483
+ * Empty for a project that declared nothing, which is every project that has
484
+ * not opted in — so this reads as a refusal by default, on purpose.
485
+ */
486
+ function declaredDatabaseExtensions() {
487
+ const names = /* @__PURE__ */ new Set();
488
+ for (const declaration of declaredResources("database")) {
489
+ const declared = declaration.options.extensions;
490
+ if (!Array.isArray(declared)) continue;
491
+ for (const name of declared) if (typeof name === "string" && name.trim()) names.add(name.trim());
492
+ }
493
+ return [...names].sort();
494
+ }
465
495
  registerResourceKind({
466
496
  kind: "bucket",
467
497
  engines: [
@@ -506,6 +536,6 @@ registerResourceKind({
506
536
  implicitDefault: false
507
537
  });
508
538
  //#endregion
509
- export { isRelationAggregateSort as _, rewriteLegacyRlsFunctions as a, toCanonicalOp as b, isPostgresCollectionConfig as c, getDataSourceCapabilities as d, ALL_WHERE_FILTER_OPS as f, encodeRelationAggregateSort as g, REST_TO_CANONICAL as h, RLS_UID_SQL as i, isRelationalCollectionConfig as l, NULL_OPS as m, REBASE_SCHEMA as n, usesLegacyRlsFunctions as o, CANONICAL_TO_REST as p, RLS_ROLES_SQL as r, getDeclaredSubcollections as s, LEGACY_RLS_SCHEMA as t, DEFAULT_DATA_SOURCE_KEY as u, parseRelationAggregateSort as v, sortKeyToString as y };
539
+ export { encodeRelationAggregateSort as _, RLS_UID_SQL as a, sortKeyToString as b, getDeclaredSubcollections as c, DEFAULT_DATA_SOURCE_KEY as d, getDataSourceCapabilities as f, REST_TO_CANONICAL as g, NULL_OPS as h, RLS_ROLES_SQL as i, isPostgresCollectionConfig as l, CANONICAL_TO_REST as m, LEGACY_RLS_SCHEMA as n, rewriteLegacyRlsFunctions as o, ALL_WHERE_FILTER_OPS as p, REBASE_SCHEMA as r, usesLegacyRlsFunctions as s, declaredDatabaseExtensions as t, isRelationalCollectionConfig as u, isRelationAggregateSort as v, toCanonicalOp as x, parseRelationAggregateSort as y };
510
540
 
511
- //# sourceMappingURL=src-DiDgtX8P.js.map
541
+ //# sourceMappingURL=src-DiB5RP2Z.js.map