@rebasepro/server-postgres 0.25.0 → 0.25.1

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 (114) hide show
  1. package/dist/{BranchService-iXXZeVYD.js → BranchService-ClklxyAQ.js} +66 -6
  2. package/dist/BranchService-ClklxyAQ.js.map +1 -0
  3. package/dist/backup/backup-cli.d.ts +40 -3
  4. package/dist/backup/backup-service.d.ts +11 -0
  5. package/dist/{backup-service-Bb39plam.js → backup-cli-gijeXe0u.js} +777 -10
  6. package/dist/backup-cli-gijeXe0u.js.map +1 -0
  7. package/dist/{boot-ddl-s_3Hkz94.js → boot-ddl-DYH95Qeg.js} +3 -3
  8. package/dist/{boot-ddl-s_3Hkz94.js.map → boot-ddl-DYH95Qeg.js.map} +1 -1
  9. package/dist/branch-argv.d.ts +15 -0
  10. package/dist/{cli-console-DQ_K-sdM.js → cli-console-CQrQ0lAY.js} +8 -9
  11. package/dist/{cli-console-DQ_K-sdM.js.map → cli-console-CQrQ0lAY.js.map} +1 -1
  12. package/dist/{cli-errors-DwQnNATs.js → cli-errors-DiA0XFIS.js} +38 -10
  13. package/dist/{cli-errors-DwQnNATs.js.map → cli-errors-DiA0XFIS.js.map} +1 -1
  14. package/dist/cli-errors.d.ts +14 -0
  15. package/dist/cli-flags.d.ts +51 -0
  16. package/dist/{cli-prompt-egtNKkZl.js → cli-prompt-DXG0yk-h.js} +39 -4
  17. package/dist/{cli-prompt-egtNKkZl.js.map → cli-prompt-DXG0yk-h.js.map} +1 -1
  18. package/dist/cli.js +44 -174
  19. package/dist/cli.js.map +1 -1
  20. package/dist/{column-plan-helpers-D_V4oaZh.js → column-plan-helpers-IG6uFb1s.js} +2 -2
  21. package/dist/{column-plan-helpers-D_V4oaZh.js.map → column-plan-helpers-IG6uFb1s.js.map} +1 -1
  22. package/dist/{connection-C938nR3E.js → connection-czvI7TZL.js} +57 -10
  23. package/dist/connection-czvI7TZL.js.map +1 -0
  24. package/dist/{databasePoolManager-Yqdw14wY.js → databasePoolManager-3stMNFL-.js} +4 -6
  25. package/dist/databasePoolManager-3stMNFL-.js.map +1 -0
  26. package/dist/db-command-line.d.ts +14 -0
  27. package/dist/{rls-bootstrap-sql-Bd-hJk08.js → db-subcommands-BPoHCxJR.js} +455 -3
  28. package/dist/db-subcommands-BPoHCxJR.js.map +1 -0
  29. package/dist/db-subcommands.d.ts +11 -0
  30. package/dist/{deferred-index-build-Cis_HoGn.js → deferred-index-build-BE0I6sYU.js} +8 -8
  31. package/dist/{deferred-index-build-Cis_HoGn.js.map → deferred-index-build-BE0I6sYU.js.map} +1 -1
  32. package/dist/{doctor-DvJH-IQG.js → doctor-BT--1kq3.js} +107 -11
  33. package/dist/doctor-BT--1kq3.js.map +1 -0
  34. package/dist/{ensure-collection-policies-CCqayoUz.js → ensure-collection-policies-BnGOURpG.js} +13 -10
  35. package/dist/ensure-collection-policies-BnGOURpG.js.map +1 -0
  36. package/dist/{ensure-collection-tables-DvvImXDe.js → ensure-collection-tables-Cet4650m.js} +9 -9
  37. package/dist/{ensure-collection-tables-DvvImXDe.js.map → ensure-collection-tables-Cet4650m.js.map} +1 -1
  38. package/dist/{ensure-tables-Dpgwx5sy.js → ensure-tables-l_OgFQjN.js} +5 -5
  39. package/dist/{ensure-tables-Dpgwx5sy.js.map → ensure-tables-l_OgFQjN.js.map} +1 -1
  40. package/dist/{enum-labels-kept-CUlUlRkO.js → enum-labels-kept-nheku1pB.js} +3 -3
  41. package/dist/{enum-labels-kept-CUlUlRkO.js.map → enum-labels-kept-nheku1pB.js.map} +1 -1
  42. package/dist/{generate-drizzle-schema-C3EAP9HE.js → generate-drizzle-schema-DC0BOUpn.js} +3 -3
  43. package/dist/{generate-drizzle-schema-C3EAP9HE.js.map → generate-drizzle-schema-DC0BOUpn.js.map} +1 -1
  44. package/dist/{generate-drizzle-schema-logic-DA3zM8zc.js → generate-drizzle-schema-logic-CPzCRD-8.js} +4 -4
  45. package/dist/{generate-drizzle-schema-logic-DA3zM8zc.js.map → generate-drizzle-schema-logic-CPzCRD-8.js.map} +1 -1
  46. package/dist/{generate-files-ClmOUHXj.js → generate-files-BP-4W_gm.js} +6 -6
  47. package/dist/{generate-files-ClmOUHXj.js.map → generate-files-BP-4W_gm.js.map} +1 -1
  48. package/dist/{generate-next-step-DCeS4LrJ.js → generate-next-step-DgK5BlBn.js} +2 -2
  49. package/dist/{generate-next-step-DCeS4LrJ.js.map → generate-next-step-DgK5BlBn.js.map} +1 -1
  50. package/dist/{generate-postgres-ddl-logic-4eUP4t8w.js → generate-postgres-ddl-logic-DPl1oH_z.js} +4 -4
  51. package/dist/{generate-postgres-ddl-logic-4eUP4t8w.js.map → generate-postgres-ddl-logic-DPl1oH_z.js.map} +1 -1
  52. package/dist/generated-schema-diff-eZCklRZQ.js +1025 -0
  53. package/dist/generated-schema-diff-eZCklRZQ.js.map +1 -0
  54. package/dist/{generated-schema-staleness-FlxM2i4i.js → generated-schema-staleness-BvNF3i-s.js} +2 -2
  55. package/dist/{generated-schema-staleness-FlxM2i4i.js.map → generated-schema-staleness-BvNF3i-s.js.map} +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.es.js +70 -11
  58. package/dist/index.es.js.map +1 -1
  59. package/dist/{introspect-db-logic-CI5CU_n0.js → introspect-db-logic-DgQVzccW.js} +2 -2
  60. package/dist/{introspect-db-logic-CI5CU_n0.js.map → introspect-db-logic-DgQVzccW.js.map} +1 -1
  61. package/dist/migrate-policy-stamps-3eqfhes6.js +89 -0
  62. package/dist/migrate-policy-stamps-3eqfhes6.js.map +1 -0
  63. package/dist/{open-rebase-BKA7Nyoe.js → open-rebase-EmqVmS14.js} +51 -1020
  64. package/dist/open-rebase-EmqVmS14.js.map +1 -0
  65. package/dist/{pg-error-utils-Bv5n2PLn.js → pg-error-utils-CFEnm2m9.js} +2 -2
  66. package/dist/{pg-error-utils-Bv5n2PLn.js.map → pg-error-utils-CFEnm2m9.js.map} +1 -1
  67. package/dist/{plan-schema-CXOucCw-.js → plan-schema-Czf3q4-Q.js} +4 -4
  68. package/dist/{plan-schema-CXOucCw-.js.map → plan-schema-Czf3q4-Q.js.map} +1 -1
  69. package/dist/{policy-drift-vm0BcvcE.js → policy-drift-X4A-xAzv.js} +3 -3
  70. package/dist/{policy-drift-vm0BcvcE.js.map → policy-drift-X4A-xAzv.js.map} +1 -1
  71. package/dist/pool-disconnects.d.ts +28 -0
  72. package/dist/{push-index-prebuild-DIequ4bV.js → push-index-prebuild-COd7i6wm.js} +4 -4
  73. package/dist/{push-index-prebuild-DIequ4bV.js.map → push-index-prebuild-COd7i6wm.js.map} +1 -1
  74. package/dist/{push-legacy-renames-BqJut4F3.js → push-legacy-renames-CLgYYwPE.js} +4 -4
  75. package/dist/{push-legacy-renames-BqJut4F3.js.map → push-legacy-renames-CLgYYwPE.js.map} +1 -1
  76. package/dist/{push-policy-plan-CvX8hiPb.js → push-policy-plan-D2gpQsdv.js} +5 -5
  77. package/dist/{push-policy-plan-CvX8hiPb.js.map → push-policy-plan-D2gpQsdv.js.map} +1 -1
  78. package/dist/{render-ddl-CQNwZdse.js → render-ddl-4v88y-Gv.js} +4 -4
  79. package/dist/{render-ddl-CQNwZdse.js.map → render-ddl-4v88y-Gv.js.map} +1 -1
  80. package/dist/{rls-enforcement-D7P4-ZYX.js → rls-enforcement-DDyNoOSy.js} +2 -2
  81. package/dist/{rls-enforcement-D7P4-ZYX.js.map → rls-enforcement-DDyNoOSy.js.map} +1 -1
  82. package/dist/schema/doctor-cli.js +5 -5
  83. package/dist/schema/doctor.d.ts +20 -2
  84. package/dist/schema/ensure-collection-policies.d.ts +4 -1
  85. package/dist/schema/generate-drizzle-schema.js +1 -1
  86. package/dist/schema/generate-postgres-ddl.js +2 -2
  87. package/dist/schema/generated-schema-diff.d.ts +21 -0
  88. package/dist/schema/introspect-db.js +5 -6
  89. package/dist/schema/introspect-db.js.map +1 -1
  90. package/dist/schema/migrate-policy-stamps.d.ts +23 -0
  91. package/dist/schema/push-policy-plan.d.ts +5 -0
  92. package/dist/services/BranchService.d.ts +20 -2
  93. package/dist/services/pg-notify-listener.d.ts +2 -0
  94. package/dist/{source-Bv5KPeIx.js → source-fZb92pN8.js} +2 -2
  95. package/dist/{source-Bv5KPeIx.js.map → source-fZb92pN8.js.map} +1 -1
  96. package/dist/{vector-index-BFhyEaiz.js → vector-index-DsQ3V2d2.js} +2 -2
  97. package/dist/{vector-index-BFhyEaiz.js.map → vector-index-DsQ3V2d2.js.map} +1 -1
  98. package/dist/{websocket-MC0zTBar.js → websocket-BKZwsjmf.js} +18 -5
  99. package/dist/websocket-BKZwsjmf.js.map +1 -0
  100. package/package.json +7 -7
  101. package/dist/BranchService-iXXZeVYD.js.map +0 -1
  102. package/dist/backup-cli-B2CAn9fR.js +0 -647
  103. package/dist/backup-cli-B2CAn9fR.js.map +0 -1
  104. package/dist/backup-service-Bb39plam.js.map +0 -1
  105. package/dist/cli-flags-D-b0qL9T.js +0 -206
  106. package/dist/cli-flags-D-b0qL9T.js.map +0 -1
  107. package/dist/connection-C938nR3E.js.map +0 -1
  108. package/dist/databasePoolManager-Yqdw14wY.js.map +0 -1
  109. package/dist/doctor-DvJH-IQG.js.map +0 -1
  110. package/dist/ensure-collection-policies-CCqayoUz.js.map +0 -1
  111. package/dist/open-rebase-BKA7Nyoe.js.map +0 -1
  112. package/dist/rls-bootstrap-sql-Bd-hJk08.js.map +0 -1
  113. package/dist/rolldown-runtime-V7rFbMRe.js +0 -39
  114. package/dist/websocket-MC0zTBar.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"source-Bv5KPeIx.js","names":["styles","process"],"sources":["../src/schema/collection-index.ts","../src/schema/atlas-exclude.ts","../src/cli-output.ts","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js"],"sourcesContent":["/**\n * The one place a collection's `indexes:` block becomes `CREATE INDEX`.\n *\n * Like `search-column.ts` and `vector-index.ts`, this module exists so the DDL\n * generator and the boot-time ensure render the *same* specification rather\n * than describing the same index twice, differently.\n *\n * ## Why every form here is core Postgres\n *\n * `rebase db push` runs `atlas schema apply`, which materialises the desired\n * state in a bare scratch database to plan against. `--exclude` does not\n * suppress that replay, and `CREATE EXTENSION` cannot go in the file. So an\n * index wanting `gin_trgm_ops` or `vector_cosine_ops` would parse, plan, and\n * then fail against a database the author has never heard of. Those are\n * refused here instead, and redirected to the feature that owns them: trigram\n * search is `search:`, ANN is a `vector` property.\n *\n * Verified against atlas v1.2.3 and Postgres 18 before this was written: plain,\n * composite with `DESC NULLS LAST`, partial, unique, covering `INCLUDE`, `GIN`\n * and expression indexes all parse, apply, and re-plan clean. The Atlas\n * limitation that forced the search carve-out is that it will not parse a file\n * containing a function *definition* — a function *call* inside an index is\n * fine. That is why this module needs no carve-out and search did.\n *\n * ## Why the name carries a hash\n *\n * `CREATE INDEX IF NOT EXISTS` is a **name** check, not a definition check. A\n * readable name means a changed declaration keeps the old index and reports\n * success, forever. Hashing the index's *semantics* into its name makes a\n * redefinition a different object: the new one is built before the old one is\n * dropped, there is never a window with no index, and drift detection reduces\n * to a set difference over names.\n */\nimport type { CollectionConfig, CollectionIndex, IndexPredicate, Property, ResolvedRelation } from \"@rebasepro/types\";\nimport { isPostgresCollectionConfig } from \"@rebasepro/types\";\nimport { getTableName, resolveCollectionRelations } from \"@rebasepro/common\";\nimport { sha1Hex, truncateToBytes } from \"@rebasepro/utils\";\n\n/** Resolve a property key to its column name. Injected to avoid an import cycle. */\nexport type ResolveColumnName = (propName: string, prop?: Property | null) => string;\n\nexport type IndexMethod = \"btree\" | \"gin\" | \"brin\";\n\n/** A key column, with the ordering Postgres will actually apply. */\nexport interface ResolvedIndexKey {\n column: string;\n /** Always concrete. `btree` defaults ascending; unordered methods report `asc`. */\n direction: \"asc\" | \"desc\";\n /** Postgres's own default: `last` under `asc`, `first` under `desc`. */\n nulls: \"first\" | \"last\";\n}\n\n/** A predicate resolved onto column names, ready to render and to hash. */\nexport type ResolvedPredicate =\n | { column: string; op: \"=\" | \"!=\" | \"<\" | \"<=\" | \">\" | \">=\"; value: string | number | boolean }\n | { column: string; op: \"is null\" | \"is not null\" }\n | { column: string; op: \"in\"; value: readonly (string | number)[] }\n | { and: readonly ResolvedPredicate[] };\n\n/** One index, fully resolved. The only shape the renderers accept. */\nexport interface CollectionIndexSpec {\n schema: string;\n table: string;\n method: IndexMethod;\n unique: boolean;\n keys: ResolvedIndexKey[];\n include: string[];\n predicate: ResolvedPredicate | null;\n /** The author's one-line justification. Never enters the name. */\n reason: string;\n /** Derived by {@link deriveIndexName}. Frozen — see the module comment. */\n indexName: string;\n /**\n * Set when Rebase derived this index for a foreign key rather than anybody\n * declaring it — see {@link foreignKeyIndexSpec}. Never enters the name, so\n * the derived index and a declared one over the same column are one object.\n *\n * Read by exactly one consumer: boot-ensure, which builds these in the\n * background on a table that already exists instead of holding the boot\n * for the build. Every renderer treats them like any other index.\n */\n derived?: \"foreign-key\";\n}\n\n/**\n * A declaration that cannot become an index.\n *\n * Thrown at build time, naming the collection and the array position, because\n * the alternative is a `CREATE INDEX` that fails during a push with a Postgres\n * error mentioning a column the author never wrote.\n */\nexport class CollectionIndexConfigError extends Error {\n readonly collectionSlug: string;\n readonly position: number;\n\n constructor(collectionSlug: string, position: number, message: string) {\n super(`${collectionSlug}.indexes[${position}]: ${message}`);\n this.name = \"CollectionIndexConfigError\";\n this.collectionSlug = collectionSlug;\n this.position = position;\n }\n}\n\n/** Postgres allows 32 key columns. See the doc comment on `on`. */\nexport const MAX_INDEX_KEYS = 5;\n\n/**\n * `_ix`/`_ux` plus `_` plus 7 hex — the part of the name that must always\n * survive truncation, and therefore is never inside the truncated portion.\n */\nconst NAME_SUFFIX_BYTES = 11;\n\n/**\n * Every Rebase-managed index name, and nothing else.\n *\n * The terminal `_ix_`/`_ux_` plus exactly seven lowercase hex characters is\n * what separates this scheme from every other producer in the codebase —\n * `_fkey`, `_gin`, `_trgm`, `_pkey`, `_key`, the vector distances, and the\n * `idx_` prefix auth uses. `_idx` was rejected as a tail because it is already\n * taken for real: `users_email_verification_token_idx` is byte-for-byte what a\n * naive `<table>_<column>_idx` derives on an auth-enabled `users` collection.\n *\n * Load-bearing for safety, not just tidiness. An index that does NOT match this\n * belongs to somebody else — a hand-written one, or one an introspected\n * database arrived with — and is excluded from the Atlas diff so the push\n * cannot drop it.\n */\nexport const isRebaseIndexName = (name: string): boolean => /_(?:ix|ux)_[0-9a-f]{7}$/.test(name);\n\nconst isOrderedMethod = (method: IndexMethod): boolean => method === \"btree\";\n\n/**\n * The parts of an index that decide what it *is*.\n *\n * A semantic projection, not the rendered statement — the same arrangement as\n * `getPolicyNameHash`, and for the same reason. A change to how this file\n * formats SQL (eliding a default `USING btree`, quoting differently, emitting\n * `NULLS LAST` explicitly) must not silently rename every index in every\n * deployed database. Hashing generator output would make every cosmetic edit a\n * fleet-wide DROP + CREATE.\n *\n * `reason` is deliberately absent: rewording a comment must not rebuild an\n * index. `nulls` is the *effective* placement, so writing Postgres's own\n * default down is a no-op rather than a redefinition.\n *\n * `v` is the only escape hatch, and it is expensive on purpose: bumping it\n * renames every index in the field.\n */\nexport const indexFingerprint = (spec: Omit<CollectionIndexSpec, \"indexName\">): string => sha1Hex(JSON.stringify({\n v: 1,\n s: spec.schema,\n t: spec.table,\n m: spec.method,\n u: spec.unique,\n k: spec.keys.map(k => [k.column, k.direction, k.nulls]),\n i: spec.include,\n w: spec.predicate\n})).substring(0, 7);\n\n/**\n * `<table>_<columns>_ix_<hash>`, or `_ux_` when unique.\n *\n * Truncation eats the readable head and never the hash. `toPostgresIdentifier`\n * truncates the whole string at 63 bytes, which on a hashed name would cut off\n * the one part that makes it unique — the failure already frozen into\n * `contracts/derived-names.txt`, where a foreign key is recorded with its\n * `_fkey` suffix truncated away, so a second foreign key on that table would\n * derive a byte-identical name.\n */\nexport const deriveIndexName = (spec: Omit<CollectionIndexSpec, \"indexName\">): string => {\n // Built suffix-first, so the two parts that carry meaning — the `_ix`/`_ux`\n // tag that {@link isRebaseIndexName} matches on, and the fingerprint — are\n // never in the string being truncated. Composing the whole name and then\n // trimming it to 63 loses both, silently: an 80-byte table name yields\n // `xxxx…xxx_610bb9e` with the tag gone, so the index stops being\n // recognisable as Rebase's and `db push` treats it as foreign forever.\n const tag = spec.unique ? \"ux\" : \"ix\";\n const suffix = `_${tag}_${indexFingerprint(spec)}`;\n const readable = `${spec.table}_${spec.keys.map(k => k.column).join(\"_\")}`;\n return `${truncateToBytes(readable, 63 - NAME_SUFFIX_BYTES)}${suffix}`;\n};\n\nconst quoteLiteral = (value: string | number | boolean): string => {\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n return `'${value.replace(/'/g, \"''\")}'`;\n};\n\n/** Render a resolved predicate as the body of a `WHERE` clause. */\nexport const renderPredicate = (predicate: ResolvedPredicate): string => {\n if (\"and\" in predicate) {\n // Always parenthesised. Postgres would apply the same precedence\n // without it, but the rendered SQL is read by people diffing a plan.\n return predicate.and.map(renderPredicate).join(\" AND \");\n }\n switch (predicate.op) {\n case \"is null\":\n case \"is not null\":\n return `\"${predicate.column}\" ${predicate.op.toUpperCase()}`;\n case \"in\":\n return `\"${predicate.column}\" IN (${predicate.value.map(quoteLiteral).join(\", \")})`;\n default:\n return `\"${predicate.column}\" ${predicate.op} ${quoteLiteral(predicate.value)}`;\n }\n};\n\n/**\n * The `CREATE INDEX` for one spec.\n *\n * `concurrently` is a parameter rather than a string replacement on the way\n * out. `search-column.ts` and `vector-index.ts` both reach for\n * `.replace(\"CREATE INDEX IF NOT EXISTS\", …)` instead, which silently does\n * nothing for a UNIQUE index — the rendered text is `CREATE UNIQUE INDEX …`\n * and the pattern never matches.\n */\nexport const collectionIndexStatement = (\n spec: CollectionIndexSpec,\n options: { concurrently?: boolean; ifNotExists?: boolean } = {}\n): string => {\n const unique = spec.unique ? \"UNIQUE \" : \"\";\n const concurrently = options.concurrently ? \"CONCURRENTLY \" : \"\";\n const ifNotExists = options.ifNotExists ? \"IF NOT EXISTS \" : \"\";\n const using = spec.method === \"btree\" ? \"\" : ` USING ${spec.method}`;\n\n const keys = spec.keys.map(k => {\n if (!isOrderedMethod(spec.method)) return `\"${k.column}\"`;\n const direction = k.direction === \"desc\" ? \" DESC\" : \"\";\n // Emitted only when it is not what the direction already implies, so\n // the rendered SQL matches what `pg_get_indexdef` reads back and a\n // re-plan finds no difference.\n const impliedNulls = k.direction === \"desc\" ? \"first\" : \"last\";\n const nulls = k.nulls === impliedNulls ? \"\" : ` NULLS ${k.nulls.toUpperCase()}`;\n return `\"${k.column}\"${direction}${nulls}`;\n }).join(\", \");\n\n const include = spec.include.length > 0\n ? ` INCLUDE (${spec.include.map(c => `\"${c}\"`).join(\", \")})`\n : \"\";\n const where = spec.predicate ? ` WHERE ${renderPredicate(spec.predicate)}` : \"\";\n\n return `CREATE ${unique}INDEX ${concurrently}${ifNotExists}\"${spec.indexName}\" ` +\n `ON \"${spec.schema}\".\"${spec.table}\"${using} (${keys})${include}${where};`;\n};\n\nexport const collectionIndexStatements = (\n specs: readonly CollectionIndexSpec[],\n options: { concurrently?: boolean; ifNotExists?: boolean } = {}\n): string[] => specs.map(spec => collectionIndexStatement(spec, options));\n\nconst relationOf = (\n collection: CollectionConfig,\n propKey: string\n): ResolvedRelation | undefined => resolveCollectionRelations(collection)[propKey];\n\n/**\n * The column a property key indexes.\n *\n * A `belongsTo` resolves to its `localKey` — `primaryCategory` becomes\n * `primary_category_id` — which is the case an index is most often wanted for\n * and the case where the property key and the column differ. Everything else\n * goes through `resolveColumnName`.\n *\n * The other relation kinds have no local column at all: the foreign key lives\n * on the target's table, or in a junction. Indexing them here is refused\n * rather than resolved to a column that does not exist.\n */\nexport const resolveIndexableColumn = (\n collection: CollectionConfig,\n propKey: string,\n resolveColumnName: ResolveColumnName,\n fail: (message: string) => never\n): string => {\n const relation = relationOf(collection, propKey);\n if (relation) {\n if (relation.kind === \"belongsTo\") return relation.localKey;\n fail(\n `\"${propKey}\" is a ${relation.kind} relation, which has no column on this table — ` +\n `the foreign key lives on \"${relation.targetSlug}\". Declare the index there.`\n );\n }\n\n const property = collection.properties?.[propKey] as Property | undefined;\n if (!property) {\n fail(`\"${propKey}\" is not a property of this collection.`);\n }\n return resolveColumnName(propKey, property);\n};\n\nconst resolvePredicate = (\n collection: CollectionConfig,\n predicate: IndexPredicate,\n resolveColumnName: ResolveColumnName,\n fail: (message: string) => never\n): ResolvedPredicate => {\n if (\"and\" in predicate) {\n return { and: predicate.and.map(p => resolvePredicate(collection, p, resolveColumnName, fail)) };\n }\n const column = resolveIndexableColumn(collection, predicate.prop, resolveColumnName, fail);\n switch (predicate.op) {\n case \"is null\":\n case \"is not null\":\n return { column, op: predicate.op };\n case \"in\": {\n const seen = new Set(predicate.value);\n if (seen.size !== predicate.value.length) {\n fail(`the \\`in\\` list for \"${predicate.prop}\" repeats a value, which changes nothing.`);\n }\n return { column, op: \"in\", value: [...predicate.value] };\n }\n default:\n return { column, op: predicate.op, value: predicate.value };\n }\n};\n\n/** The primary key columns of a collection, for the \"you already have this\" refusal. */\nconst primaryKeyColumns = (collection: CollectionConfig, resolveColumnName: ResolveColumnName): string[] =>\n Object.entries(collection.properties ?? {})\n .filter(([, prop]) => prop && typeof prop === \"object\" && \"isId\" in prop && Boolean((prop as { isId?: unknown }).isId))\n .map(([key, prop]) => resolveColumnName(key, prop as Property));\n\n/**\n * Every index one collection declares, resolved and named.\n *\n * Throws {@link CollectionIndexConfigError} rather than dropping a bad entry:\n * an index that silently does not exist is the failure mode this whole feature\n * is here to remove.\n */\nexport const buildCollectionIndexSpecs = (\n collection: CollectionConfig,\n resolveColumnName: ResolveColumnName\n): CollectionIndexSpec[] => {\n if (!isPostgresCollectionConfig(collection)) return [];\n const declared = collection.indexes;\n if (!declared || declared.length === 0) return [];\n\n const slug = collection.slug ?? getTableName(collection);\n const schema = collection.schema ?? \"public\";\n const table = getTableName(collection);\n const pk = primaryKeyColumns(collection, resolveColumnName).sort().join(\",\");\n\n const specs: CollectionIndexSpec[] = [];\n const byName = new Map<string, number>();\n\n declared.forEach((index: CollectionIndex, position: number) => {\n const fail = (message: string): never => {\n throw new CollectionIndexConfigError(slug, position, message);\n };\n\n if (typeof index.reason !== \"string\" || index.reason.trim() === \"\") {\n fail(\"`reason` is required — see the doc comment. An index nobody can justify is one nobody can delete.\");\n }\n if (!Array.isArray(index.on) || index.on.length === 0) {\n fail(\"`on` must name at least one property.\");\n }\n if (index.on.length > MAX_INDEX_KEYS) {\n fail(`\\`on\\` has ${index.on.length} keys; the limit is ${MAX_INDEX_KEYS}. Payload columns belong in \\`include\\`.`);\n }\n\n const method: IndexMethod = index.using ?? \"btree\";\n const unique = method === \"btree\" && Boolean((index as { unique?: boolean }).unique);\n if (!isOrderedMethod(method)) {\n for (const key of index.on) {\n if (typeof key !== \"string\" && (\"direction\" in key || \"nulls\" in key)) {\n fail(`access method \"${method}\" does not support ASC/DESC or NULLS options.`);\n }\n }\n }\n\n const keys: ResolvedIndexKey[] = index.on.map(key => {\n const propKey = typeof key === \"string\" ? key : key.prop;\n const column = resolveIndexableColumn(collection, propKey, resolveColumnName, fail);\n const direction = (typeof key === \"string\" ? undefined : (key as { direction?: \"asc\" | \"desc\" }).direction) ?? \"asc\";\n const nulls = (typeof key === \"string\" ? undefined : (key as { nulls?: \"first\" | \"last\" }).nulls)\n ?? (direction === \"desc\" ? \"first\" : \"last\");\n return { column, direction, nulls };\n });\n\n const duplicateKey = keys.map(k => k.column).find((c, i, all) => all.indexOf(c) !== i);\n if (duplicateKey) fail(`\"${duplicateKey}\" appears twice in \\`on\\`.`);\n\n if (keys.map(k => k.column).sort().join(\",\") === pk && pk !== \"\") {\n fail(`this is the primary key — \"${table}_pkey\" already indexes exactly these columns.`);\n }\n\n const include = ((index as { include?: readonly string[] }).include ?? [])\n .map(propKey => resolveIndexableColumn(collection, propKey, resolveColumnName, fail));\n const overlap = include.find(c => keys.some(k => k.column === c));\n if (overlap) fail(`\"${overlap}\" is in both \\`on\\` and \\`include\\`; Postgres rejects the overlap.`);\n\n if (unique && keys.length === 1) {\n const propKey = typeof index.on[0] === \"string\" ? index.on[0] as string : (index.on[0] as { prop: string }).prop;\n const property = collection.properties?.[propKey] as { validation?: { unique?: boolean } } | undefined;\n if (property?.validation?.unique) {\n fail(\n `\"${propKey}\" already declares \\`validation.unique\\`, which compiles to an inline UNIQUE. ` +\n `Two declarations of one guarantee — remove one.`\n );\n }\n }\n\n const predicate = index.where\n ? resolvePredicate(collection, index.where, resolveColumnName, fail)\n : null;\n\n const withoutName = { schema, table, method, unique, keys, include, predicate, reason: index.reason };\n const indexName = deriveIndexName(withoutName);\n\n const clash = byName.get(indexName);\n if (clash !== undefined) {\n fail(`derives the same name as indexes[${clash}] — they are the same index declared twice.`);\n }\n byName.set(indexName, position);\n\n specs.push({ ...withoutName, indexName });\n });\n\n return specs;\n};\n\n/**\n * Every declared index across a set of collections, in a stable order.\n *\n * Sorted because the result reaches `schema.sql`, which `doctor` string-\n * compares against a regenerated copy — `generatePostgresDdl` does not sort its\n * collections, so leaving this in declaration order would make the artifact\n * depend on the order files happened to load in.\n */\nexport const buildCollectionIndexPlan = (\n collections: readonly CollectionConfig[],\n resolveColumnName: ResolveColumnName\n): CollectionIndexSpec[] =>\n sortIndexSpecs(collections.flatMap(collection => buildCollectionIndexSpecs(collection, resolveColumnName)));\n\n/**\n * The stable order every consumer of a set of index specs uses.\n *\n * Exported because the boot-time diff reads the specs off the schema plan\n * rather than rebuilding them, and it has to reach the same order the CLI's\n * exclude list and `schema.sql` do — a second sort written out beside this one\n * is a second order the moment either is edited.\n */\nexport const sortIndexSpecs = (specs: readonly CollectionIndexSpec[]): CollectionIndexSpec[] =>\n [...specs].sort((a, b) =>\n a.schema.localeCompare(b.schema) ||\n a.table.localeCompare(b.table) ||\n a.indexName.localeCompare(b.indexName));\n\n// ── Foreign-key indexes ──────────────────────────────────────────────────────\n\n/**\n * The `reason` a derived foreign-key index carries. Never part of the name —\n * see {@link indexFingerprint} — so rewording it renames nothing.\n */\nexport const FOREIGN_KEY_INDEX_REASON =\n \"Derived for a foreign key: Postgres indexes the key a constraint points at, never the column holding it.\";\n\n/**\n * Whether an index already serves an equality lookup on `column` alone.\n *\n * A btree whose *leading* key is the column does, unique or not — that is the\n * prefix rule, and it is why a composite `(author_id, created_at)` makes a\n * second index on `author_id` pure write amplification. A partial index does\n * not: it serves only the rows its predicate admits, and a foreign-key lookup\n * has to reach every row. Nor does GIN or BRIN, which answer different\n * questions than \"the rows whose key is one of these\".\n */\nexport const leadsWithColumn = (spec: Pick<CollectionIndexSpec, \"method\" | \"predicate\" | \"keys\">, column: string): boolean =>\n spec.method === \"btree\" && spec.predicate === null && spec.keys[0]?.column === column;\n\n/**\n * The btree a foreign-key column gets when nothing else already leads with it.\n *\n * Postgres creates the index a foreign key *references* (the target's primary\n * key) and never the one on the column *holding* it. Every read from the other\n * side of the link filters on that column — a `hasMany`/`hasOne` include, a\n * nested listing (`/authors/5/posts`, page and count), the reverse side of a\n * many-to-many — and so does the `ON DELETE` check when a target row goes. With\n * no index each of those is a sequential scan of the child table: measured at\n * 13 ms for 25 parents over 100k children, and about 250 ms per nested listing\n * at a million.\n *\n * Named by {@link deriveIndexName} like every other index, so it is a\n * Rebase-managed name (`_ix_<fingerprint>`), it is in the Atlas diff, and it\n * is byte-for-byte the name an author's own plain index on the column would\n * derive. That identity is what makes the derived index and a declared one the\n * same object rather than two.\n */\nexport const foreignKeyIndexSpec = (schema: string, table: string, column: string): CollectionIndexSpec => {\n const withoutName = {\n schema,\n table,\n method: \"btree\" as const,\n unique: false,\n keys: [{ column, direction: \"asc\" as const, nulls: \"last\" as const }],\n include: [],\n predicate: null,\n reason: FOREIGN_KEY_INDEX_REASON\n };\n return { ...withoutName, indexName: deriveIndexName(withoutName), derived: \"foreign-key\" };\n};\n","/**\n * The names `db push` hands Atlas's `--exclude`, spelled so they match.\n *\n * An exclude is the only thing between `atlas schema apply --auto-approve` and\n * an object Rebase does not own: a table no collection backs, a hand-written\n * index, a CHECK constraint, the search and vector columns Rebase applies\n * itself. Atlas reads each one as a glob split on `.`, so a name is not a\n * pattern as it stands. Measured against the pinned 1.2.3:\n *\n * - a `.` in a name makes one more part, and Atlas refuses the whole command,\n * `too many parts in pattern` — so every push fails on that database;\n * - `[`, `]`, `*` and `?` are glob syntax. `[v1]` is a class matching `v` or\n * `1`, so `idx[v1]` matches `idxv` and not the index called `idx[v1]`:\n * nothing is excluded, nothing is reported, and Atlas plans the drop. For\n * an index that drop is not gated, so it applied without a word.\n *\n * So each part is escaped on its own and the parts are joined: a `.` becomes\n * `?`, which matches it (and any one character, so a pattern that also keeps a\n * near-namesake errs on the side of keeping), and glob syntax is escaped with\n * `\\`, which Atlas reads as the literal.\n *\n * Code that reads these patterns back — the migration stripper, the generated\n * column ownership check, the index ownership check — reads them with\n * {@link excludePatternParts}, the exact inverse for a pattern built here.\n */\n\n/** One part of an Atlas `--exclude` pattern that matches exactly this name. */\nexport function atlasExcludeSegment(name: string): string {\n return name.replace(/[\\\\*?[\\]]/g, ch => `\\\\${ch}`).replace(/\\./g, \"?\");\n}\n\n/**\n * The pattern that matches exactly the object these names qualify:\n * `(schema, table)` for a table, `(schema, table, object)` for a column, an\n * index or a constraint. Three parts for anything on a table: a two-part\n * pattern reads as a table, matches nothing, and reports no error.\n */\nexport function atlasExcludePattern(...parts: string[]): string {\n return parts.map(atlasExcludeSegment).join(\".\");\n}\n\n/**\n * The names a pattern from {@link atlasExcludePattern} was built from, or\n * `undefined` for one that is not a plain name — a wildcard such as `auth.*`.\n *\n * Exact for every pattern built there: a `\\` escapes the character after it,\n * and an unescaped `?` can only be a dot.\n */\nexport function excludePatternParts(pattern: string): string[] | undefined {\n const parts: string[] = [];\n for (const segment of pattern.split(\".\")) {\n let name = \"\";\n for (let i = 0; i < segment.length; i++) {\n const ch = segment[i];\n if (ch === \"\\\\\" && i + 1 < segment.length) {\n name += segment[++i];\n } else if (ch === \"?\") {\n name += \".\";\n } else if (ch === \"*\" || ch === \"[\" || ch === \"]\") {\n return undefined;\n } else {\n name += ch;\n }\n }\n parts.push(name);\n }\n return parts;\n}\n","/**\n * Terminal output for the `rebase db|schema|doctor` commands.\n *\n * These commands used to write every line through `logger`, and that is a\n * category error with three separate consequences:\n *\n * - `logger` prefixes each line with its own level, so a box-drawn report\n * arrived as `ℹ️ [INFO] ┌─ ✗ Missing Column ───` and the frame no longer\n * lined up with anything;\n * - `logger` is gated by `LOG_LEVEL`, which ships in the scaffold's own\n * `.env.example` — a developer who quietened their dev server with\n * `LOG_LEVEL=warn` got a `rebase db push` that printed almost nothing and\n * still exited non-zero, indistinguishable from a crash;\n * - under `NODE_ENV=production` `logger` emits JSON, so the whole report\n * became log records with the chalk escape codes embedded in them.\n *\n * A CLI's report *is* its return value. It goes to the terminal unconditionally\n * and unadorned. `packages/cli` has always written its output this way; this is\n * the same three functions for the plugin CLI that `rebase` delegates to.\n *\n * `logger` still belongs in this package's *runtime* — a request handler has no\n * terminal and its lines want levels, timestamps and redaction. The rule is the\n * caller, not the severity: anything a developer reads because they typed a\n * command goes here, anything a server emits while running goes to `logger`.\n *\n * Errors and warnings go to stderr so `rebase db push > plan.txt` keeps the\n * diagnosis on the terminal where it is readable.\n */\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\n/** One line of human-facing output on stdout. */\nexport const out = (line = \"\"): void => {\n console.log(line);\n};\n\n/** One line of human-facing warning output on stderr. */\nexport const outWarn = (line = \"\"): void => {\n console.warn(line);\n};\n\n/** One line of human-facing error output on stderr. */\nexport const outError = (line = \"\"): void => {\n console.error(line);\n};\n\n/**\n * Whether a failure should be printed with its stack — `rebase --debug`, which\n * the launcher passes down as `REBASE_DEBUG`, or `REBASE_DEBUG` set by hand.\n */\nexport const wantsStack = (): boolean => parseEnvBoolean(process.env.REBASE_DEBUG) === true;\n\n/**\n * An error as a person reads it: its message, and its stack only under\n * `--debug`.\n *\n * The rule `rebase` itself follows (`bin/rebase.js`). These commands run in a\n * child process the launcher's handler never sees, so a syntax error in a\n * collection file reached the terminal as `Doctor failed CollectionConfigError:`\n * followed by twenty frames of loader internals, under a sentence that already\n * said which file and which line.\n */\nexport const describeFailure = (error: unknown): string => {\n if (!(error instanceof Error)) return String(error);\n const failedQuery = describeFailedQuery(error);\n const lead = failedQuery?.reason ? `${failedQuery.reason}\\n ` : \"\";\n if (wantsStack() && error.stack) {\n if (!failedQuery) return error.stack;\n // The stack opens with the message, `params:` line and all.\n const opening = `${error.name}: ${error.message}`;\n const frames = error.stack.startsWith(opening) ? error.stack.slice(opening.length) : `\\n${error.stack}`;\n return `${lead}${error.name}: ${failedQuery.query}${frames}`;\n }\n if (failedQuery) return `${lead}${failedQuery.query}\\n Re-run with --debug for the stack trace.`;\n return `${error.message}\\n Re-run with --debug for the stack trace.`;\n};\n\n/**\n * A failed query as a reader needs it: why it failed — Postgres' own reason\n * with its SQLSTATE (`relation \"nope_table\" does not exist (42P01)`), or the\n * driver's when Postgres never answered — and the query without the values it\n * ran with. `null` for any other error.\n *\n * Drizzle reports a failed query as `Failed query: <sql>` and a `params:` line\n * and keeps the error underneath in `cause`, so the message alone names a query\n * and no reason: `rebase console -e` printed exactly that, `--debug` included.\n * The values stay off the terminal: they are whatever the code passed, a\n * password hash or a token as readily as an id.\n */\nfunction describeFailedQuery(error: Error): { reason: string | null; query: string } | null {\n if (!error.message.startsWith(\"Failed query:\")) return null;\n const paramsAt = error.message.lastIndexOf(\"\\nparams:\");\n const postgres = postgresError(error.cause);\n return {\n reason: postgres ? `${postgres.message} (${postgres.code})` : deepestMessage(error.cause),\n query: paramsAt === -1 ? error.message : error.message.slice(0, paramsAt)\n };\n}\n\n/** The error Postgres raised, from a cause chain: the one carrying a SQLSTATE. */\nfunction postgresError(cause: unknown, depth = 0): { code: string; message: string } | null {\n if (!(cause instanceof Error) || depth > 5) return null;\n if (\"code\" in cause && typeof cause.code === \"string\" && /^[0-9A-Z]{5}$/.test(cause.code) && cause.message) {\n return { code: cause.code, message: cause.message };\n }\n return postgresError(cause.cause, depth + 1);\n}\n\n/** The innermost message in a cause chain, or `null` when there is none. */\nfunction deepestMessage(cause: unknown, depth = 0): string | null {\n if (!(cause instanceof Error) || depth > 5) return null;\n return deepestMessage(cause.cause, depth + 1) ?? (cause.message || null);\n}\n","const ANSI_BACKGROUND_OFFSET = 10;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u001B[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u001B[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u001B[${38 + offset};2;${red};${green};${blue}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u001B[${style[0]}m`,\n\t\t\t\tclose: `\\u001B[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\tcodes.set(style[0], style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u001B[39m';\n\tstyles.bgColor.close = '\\u001B[49m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[a-f\\d]{6}|[a-f\\d]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n","import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\n/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\nfunction envForceColor() {\n\tif ('FORCE_COLOR' in env) {\n\t\tif (env.FORCE_COLOR === 'true') {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (env.FORCE_COLOR === 'false') {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-ghostty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'wezterm') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n","// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.\nexport function stringReplaceAll(string, substring, replacer) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + replacer;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst gotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n","import ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\nimport { // eslint-disable-line import/order\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\n\n// `supportsColor.level` → `ansiStyles.color[name]` mapping\nconst levelMapping = [\n\t'ansi',\n\t'ansi',\n\t'ansi256',\n\t'ansi16m',\n];\n\nconst styles = Object.create(null);\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {\n\t\tthrow new Error('The `level` option should be an integer from 0 to 3');\n\t}\n\n\t// Detect level if not set manually\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject.level = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\nconst getModelAnsi = (model, level, type, ...arguments_) => {\n\tif (model === 'rgb') {\n\t\tif (level === 'ansi16m') {\n\t\t\treturn ansiStyles[type].ansi16m(...arguments_);\n\t\t}\n\n\t\tif (level === 'ansi256') {\n\t\t\treturn ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));\n\t\t}\n\n\t\treturn ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));\n\t}\n\n\tif (model === 'hex') {\n\t\treturn getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));\n\t}\n\n\treturn ansiStyles[type][model](...arguments_);\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tstyles[model] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n\n\tconst bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);\n\tstyles[bgModel] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n}\n\nconst proto = Object.defineProperties(() => {}, {\n\t...styles,\n\tlevel: {\n\t\tenumerable: true,\n\t\tget() {\n\t\t\treturn this[GENERATOR].level;\n\t\t},\n\t\tset(level) {\n\t\t\tthis[GENERATOR].level = level;\n\t\t},\n\t},\n});\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\t// eslint-disable-next-line no-implicit-coercion\n\tconst builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\tbuilder[GENERATOR] = self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\tif (self.level <= 0 || !string) {\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u001B')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\nObject.defineProperties(createChalk.prototype, styles);\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n"],"x_google_ignoreList":[3,4,5,6],"mappings":"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"}
1
+ {"version":3,"file":"source-fZb92pN8.js","names":["styles","process"],"sources":["../src/schema/collection-index.ts","../src/schema/atlas-exclude.ts","../src/cli-output.ts","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js","../../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js"],"sourcesContent":["/**\n * The one place a collection's `indexes:` block becomes `CREATE INDEX`.\n *\n * Like `search-column.ts` and `vector-index.ts`, this module exists so the DDL\n * generator and the boot-time ensure render the *same* specification rather\n * than describing the same index twice, differently.\n *\n * ## Why every form here is core Postgres\n *\n * `rebase db push` runs `atlas schema apply`, which materialises the desired\n * state in a bare scratch database to plan against. `--exclude` does not\n * suppress that replay, and `CREATE EXTENSION` cannot go in the file. So an\n * index wanting `gin_trgm_ops` or `vector_cosine_ops` would parse, plan, and\n * then fail against a database the author has never heard of. Those are\n * refused here instead, and redirected to the feature that owns them: trigram\n * search is `search:`, ANN is a `vector` property.\n *\n * Verified against atlas v1.2.3 and Postgres 18 before this was written: plain,\n * composite with `DESC NULLS LAST`, partial, unique, covering `INCLUDE`, `GIN`\n * and expression indexes all parse, apply, and re-plan clean. The Atlas\n * limitation that forced the search carve-out is that it will not parse a file\n * containing a function *definition* — a function *call* inside an index is\n * fine. That is why this module needs no carve-out and search did.\n *\n * ## Why the name carries a hash\n *\n * `CREATE INDEX IF NOT EXISTS` is a **name** check, not a definition check. A\n * readable name means a changed declaration keeps the old index and reports\n * success, forever. Hashing the index's *semantics* into its name makes a\n * redefinition a different object: the new one is built before the old one is\n * dropped, there is never a window with no index, and drift detection reduces\n * to a set difference over names.\n */\nimport type { CollectionConfig, CollectionIndex, IndexPredicate, Property, ResolvedRelation } from \"@rebasepro/types\";\nimport { isPostgresCollectionConfig } from \"@rebasepro/types\";\nimport { getTableName, resolveCollectionRelations } from \"@rebasepro/common\";\nimport { sha1Hex, truncateToBytes } from \"@rebasepro/utils\";\n\n/** Resolve a property key to its column name. Injected to avoid an import cycle. */\nexport type ResolveColumnName = (propName: string, prop?: Property | null) => string;\n\nexport type IndexMethod = \"btree\" | \"gin\" | \"brin\";\n\n/** A key column, with the ordering Postgres will actually apply. */\nexport interface ResolvedIndexKey {\n column: string;\n /** Always concrete. `btree` defaults ascending; unordered methods report `asc`. */\n direction: \"asc\" | \"desc\";\n /** Postgres's own default: `last` under `asc`, `first` under `desc`. */\n nulls: \"first\" | \"last\";\n}\n\n/** A predicate resolved onto column names, ready to render and to hash. */\nexport type ResolvedPredicate =\n | { column: string; op: \"=\" | \"!=\" | \"<\" | \"<=\" | \">\" | \">=\"; value: string | number | boolean }\n | { column: string; op: \"is null\" | \"is not null\" }\n | { column: string; op: \"in\"; value: readonly (string | number)[] }\n | { and: readonly ResolvedPredicate[] };\n\n/** One index, fully resolved. The only shape the renderers accept. */\nexport interface CollectionIndexSpec {\n schema: string;\n table: string;\n method: IndexMethod;\n unique: boolean;\n keys: ResolvedIndexKey[];\n include: string[];\n predicate: ResolvedPredicate | null;\n /** The author's one-line justification. Never enters the name. */\n reason: string;\n /** Derived by {@link deriveIndexName}. Frozen — see the module comment. */\n indexName: string;\n /**\n * Set when Rebase derived this index for a foreign key rather than anybody\n * declaring it — see {@link foreignKeyIndexSpec}. Never enters the name, so\n * the derived index and a declared one over the same column are one object.\n *\n * Read by exactly one consumer: boot-ensure, which builds these in the\n * background on a table that already exists instead of holding the boot\n * for the build. Every renderer treats them like any other index.\n */\n derived?: \"foreign-key\";\n}\n\n/**\n * A declaration that cannot become an index.\n *\n * Thrown at build time, naming the collection and the array position, because\n * the alternative is a `CREATE INDEX` that fails during a push with a Postgres\n * error mentioning a column the author never wrote.\n */\nexport class CollectionIndexConfigError extends Error {\n readonly collectionSlug: string;\n readonly position: number;\n\n constructor(collectionSlug: string, position: number, message: string) {\n super(`${collectionSlug}.indexes[${position}]: ${message}`);\n this.name = \"CollectionIndexConfigError\";\n this.collectionSlug = collectionSlug;\n this.position = position;\n }\n}\n\n/** Postgres allows 32 key columns. See the doc comment on `on`. */\nexport const MAX_INDEX_KEYS = 5;\n\n/**\n * `_ix`/`_ux` plus `_` plus 7 hex — the part of the name that must always\n * survive truncation, and therefore is never inside the truncated portion.\n */\nconst NAME_SUFFIX_BYTES = 11;\n\n/**\n * Every Rebase-managed index name, and nothing else.\n *\n * The terminal `_ix_`/`_ux_` plus exactly seven lowercase hex characters is\n * what separates this scheme from every other producer in the codebase —\n * `_fkey`, `_gin`, `_trgm`, `_pkey`, `_key`, the vector distances, and the\n * `idx_` prefix auth uses. `_idx` was rejected as a tail because it is already\n * taken for real: `users_email_verification_token_idx` is byte-for-byte what a\n * naive `<table>_<column>_idx` derives on an auth-enabled `users` collection.\n *\n * Load-bearing for safety, not just tidiness. An index that does NOT match this\n * belongs to somebody else — a hand-written one, or one an introspected\n * database arrived with — and is excluded from the Atlas diff so the push\n * cannot drop it.\n */\nexport const isRebaseIndexName = (name: string): boolean => /_(?:ix|ux)_[0-9a-f]{7}$/.test(name);\n\nconst isOrderedMethod = (method: IndexMethod): boolean => method === \"btree\";\n\n/**\n * The parts of an index that decide what it *is*.\n *\n * A semantic projection, not the rendered statement — the same arrangement as\n * `getPolicyNameHash`, and for the same reason. A change to how this file\n * formats SQL (eliding a default `USING btree`, quoting differently, emitting\n * `NULLS LAST` explicitly) must not silently rename every index in every\n * deployed database. Hashing generator output would make every cosmetic edit a\n * fleet-wide DROP + CREATE.\n *\n * `reason` is deliberately absent: rewording a comment must not rebuild an\n * index. `nulls` is the *effective* placement, so writing Postgres's own\n * default down is a no-op rather than a redefinition.\n *\n * `v` is the only escape hatch, and it is expensive on purpose: bumping it\n * renames every index in the field.\n */\nexport const indexFingerprint = (spec: Omit<CollectionIndexSpec, \"indexName\">): string => sha1Hex(JSON.stringify({\n v: 1,\n s: spec.schema,\n t: spec.table,\n m: spec.method,\n u: spec.unique,\n k: spec.keys.map(k => [k.column, k.direction, k.nulls]),\n i: spec.include,\n w: spec.predicate\n})).substring(0, 7);\n\n/**\n * `<table>_<columns>_ix_<hash>`, or `_ux_` when unique.\n *\n * Truncation eats the readable head and never the hash. `toPostgresIdentifier`\n * truncates the whole string at 63 bytes, which on a hashed name would cut off\n * the one part that makes it unique — the failure already frozen into\n * `contracts/derived-names.txt`, where a foreign key is recorded with its\n * `_fkey` suffix truncated away, so a second foreign key on that table would\n * derive a byte-identical name.\n */\nexport const deriveIndexName = (spec: Omit<CollectionIndexSpec, \"indexName\">): string => {\n // Built suffix-first, so the two parts that carry meaning — the `_ix`/`_ux`\n // tag that {@link isRebaseIndexName} matches on, and the fingerprint — are\n // never in the string being truncated. Composing the whole name and then\n // trimming it to 63 loses both, silently: an 80-byte table name yields\n // `xxxx…xxx_610bb9e` with the tag gone, so the index stops being\n // recognisable as Rebase's and `db push` treats it as foreign forever.\n const tag = spec.unique ? \"ux\" : \"ix\";\n const suffix = `_${tag}_${indexFingerprint(spec)}`;\n const readable = `${spec.table}_${spec.keys.map(k => k.column).join(\"_\")}`;\n return `${truncateToBytes(readable, 63 - NAME_SUFFIX_BYTES)}${suffix}`;\n};\n\nconst quoteLiteral = (value: string | number | boolean): string => {\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n return `'${value.replace(/'/g, \"''\")}'`;\n};\n\n/** Render a resolved predicate as the body of a `WHERE` clause. */\nexport const renderPredicate = (predicate: ResolvedPredicate): string => {\n if (\"and\" in predicate) {\n // Always parenthesised. Postgres would apply the same precedence\n // without it, but the rendered SQL is read by people diffing a plan.\n return predicate.and.map(renderPredicate).join(\" AND \");\n }\n switch (predicate.op) {\n case \"is null\":\n case \"is not null\":\n return `\"${predicate.column}\" ${predicate.op.toUpperCase()}`;\n case \"in\":\n return `\"${predicate.column}\" IN (${predicate.value.map(quoteLiteral).join(\", \")})`;\n default:\n return `\"${predicate.column}\" ${predicate.op} ${quoteLiteral(predicate.value)}`;\n }\n};\n\n/**\n * The `CREATE INDEX` for one spec.\n *\n * `concurrently` is a parameter rather than a string replacement on the way\n * out. `search-column.ts` and `vector-index.ts` both reach for\n * `.replace(\"CREATE INDEX IF NOT EXISTS\", …)` instead, which silently does\n * nothing for a UNIQUE index — the rendered text is `CREATE UNIQUE INDEX …`\n * and the pattern never matches.\n */\nexport const collectionIndexStatement = (\n spec: CollectionIndexSpec,\n options: { concurrently?: boolean; ifNotExists?: boolean } = {}\n): string => {\n const unique = spec.unique ? \"UNIQUE \" : \"\";\n const concurrently = options.concurrently ? \"CONCURRENTLY \" : \"\";\n const ifNotExists = options.ifNotExists ? \"IF NOT EXISTS \" : \"\";\n const using = spec.method === \"btree\" ? \"\" : ` USING ${spec.method}`;\n\n const keys = spec.keys.map(k => {\n if (!isOrderedMethod(spec.method)) return `\"${k.column}\"`;\n const direction = k.direction === \"desc\" ? \" DESC\" : \"\";\n // Emitted only when it is not what the direction already implies, so\n // the rendered SQL matches what `pg_get_indexdef` reads back and a\n // re-plan finds no difference.\n const impliedNulls = k.direction === \"desc\" ? \"first\" : \"last\";\n const nulls = k.nulls === impliedNulls ? \"\" : ` NULLS ${k.nulls.toUpperCase()}`;\n return `\"${k.column}\"${direction}${nulls}`;\n }).join(\", \");\n\n const include = spec.include.length > 0\n ? ` INCLUDE (${spec.include.map(c => `\"${c}\"`).join(\", \")})`\n : \"\";\n const where = spec.predicate ? ` WHERE ${renderPredicate(spec.predicate)}` : \"\";\n\n return `CREATE ${unique}INDEX ${concurrently}${ifNotExists}\"${spec.indexName}\" ` +\n `ON \"${spec.schema}\".\"${spec.table}\"${using} (${keys})${include}${where};`;\n};\n\nexport const collectionIndexStatements = (\n specs: readonly CollectionIndexSpec[],\n options: { concurrently?: boolean; ifNotExists?: boolean } = {}\n): string[] => specs.map(spec => collectionIndexStatement(spec, options));\n\nconst relationOf = (\n collection: CollectionConfig,\n propKey: string\n): ResolvedRelation | undefined => resolveCollectionRelations(collection)[propKey];\n\n/**\n * The column a property key indexes.\n *\n * A `belongsTo` resolves to its `localKey` — `primaryCategory` becomes\n * `primary_category_id` — which is the case an index is most often wanted for\n * and the case where the property key and the column differ. Everything else\n * goes through `resolveColumnName`.\n *\n * The other relation kinds have no local column at all: the foreign key lives\n * on the target's table, or in a junction. Indexing them here is refused\n * rather than resolved to a column that does not exist.\n */\nexport const resolveIndexableColumn = (\n collection: CollectionConfig,\n propKey: string,\n resolveColumnName: ResolveColumnName,\n fail: (message: string) => never\n): string => {\n const relation = relationOf(collection, propKey);\n if (relation) {\n if (relation.kind === \"belongsTo\") return relation.localKey;\n fail(\n `\"${propKey}\" is a ${relation.kind} relation, which has no column on this table — ` +\n `the foreign key lives on \"${relation.targetSlug}\". Declare the index there.`\n );\n }\n\n const property = collection.properties?.[propKey] as Property | undefined;\n if (!property) {\n fail(`\"${propKey}\" is not a property of this collection.`);\n }\n return resolveColumnName(propKey, property);\n};\n\nconst resolvePredicate = (\n collection: CollectionConfig,\n predicate: IndexPredicate,\n resolveColumnName: ResolveColumnName,\n fail: (message: string) => never\n): ResolvedPredicate => {\n if (\"and\" in predicate) {\n return { and: predicate.and.map(p => resolvePredicate(collection, p, resolveColumnName, fail)) };\n }\n const column = resolveIndexableColumn(collection, predicate.prop, resolveColumnName, fail);\n switch (predicate.op) {\n case \"is null\":\n case \"is not null\":\n return { column, op: predicate.op };\n case \"in\": {\n const seen = new Set(predicate.value);\n if (seen.size !== predicate.value.length) {\n fail(`the \\`in\\` list for \"${predicate.prop}\" repeats a value, which changes nothing.`);\n }\n return { column, op: \"in\", value: [...predicate.value] };\n }\n default:\n return { column, op: predicate.op, value: predicate.value };\n }\n};\n\n/** The primary key columns of a collection, for the \"you already have this\" refusal. */\nconst primaryKeyColumns = (collection: CollectionConfig, resolveColumnName: ResolveColumnName): string[] =>\n Object.entries(collection.properties ?? {})\n .filter(([, prop]) => prop && typeof prop === \"object\" && \"isId\" in prop && Boolean((prop as { isId?: unknown }).isId))\n .map(([key, prop]) => resolveColumnName(key, prop as Property));\n\n/**\n * Every index one collection declares, resolved and named.\n *\n * Throws {@link CollectionIndexConfigError} rather than dropping a bad entry:\n * an index that silently does not exist is the failure mode this whole feature\n * is here to remove.\n */\nexport const buildCollectionIndexSpecs = (\n collection: CollectionConfig,\n resolveColumnName: ResolveColumnName\n): CollectionIndexSpec[] => {\n if (!isPostgresCollectionConfig(collection)) return [];\n const declared = collection.indexes;\n if (!declared || declared.length === 0) return [];\n\n const slug = collection.slug ?? getTableName(collection);\n const schema = collection.schema ?? \"public\";\n const table = getTableName(collection);\n const pk = primaryKeyColumns(collection, resolveColumnName).sort().join(\",\");\n\n const specs: CollectionIndexSpec[] = [];\n const byName = new Map<string, number>();\n\n declared.forEach((index: CollectionIndex, position: number) => {\n const fail = (message: string): never => {\n throw new CollectionIndexConfigError(slug, position, message);\n };\n\n if (typeof index.reason !== \"string\" || index.reason.trim() === \"\") {\n fail(\"`reason` is required — see the doc comment. An index nobody can justify is one nobody can delete.\");\n }\n if (!Array.isArray(index.on) || index.on.length === 0) {\n fail(\"`on` must name at least one property.\");\n }\n if (index.on.length > MAX_INDEX_KEYS) {\n fail(`\\`on\\` has ${index.on.length} keys; the limit is ${MAX_INDEX_KEYS}. Payload columns belong in \\`include\\`.`);\n }\n\n const method: IndexMethod = index.using ?? \"btree\";\n const unique = method === \"btree\" && Boolean((index as { unique?: boolean }).unique);\n if (!isOrderedMethod(method)) {\n for (const key of index.on) {\n if (typeof key !== \"string\" && (\"direction\" in key || \"nulls\" in key)) {\n fail(`access method \"${method}\" does not support ASC/DESC or NULLS options.`);\n }\n }\n }\n\n const keys: ResolvedIndexKey[] = index.on.map(key => {\n const propKey = typeof key === \"string\" ? key : key.prop;\n const column = resolveIndexableColumn(collection, propKey, resolveColumnName, fail);\n const direction = (typeof key === \"string\" ? undefined : (key as { direction?: \"asc\" | \"desc\" }).direction) ?? \"asc\";\n const nulls = (typeof key === \"string\" ? undefined : (key as { nulls?: \"first\" | \"last\" }).nulls)\n ?? (direction === \"desc\" ? \"first\" : \"last\");\n return { column, direction, nulls };\n });\n\n const duplicateKey = keys.map(k => k.column).find((c, i, all) => all.indexOf(c) !== i);\n if (duplicateKey) fail(`\"${duplicateKey}\" appears twice in \\`on\\`.`);\n\n if (keys.map(k => k.column).sort().join(\",\") === pk && pk !== \"\") {\n fail(`this is the primary key — \"${table}_pkey\" already indexes exactly these columns.`);\n }\n\n const include = ((index as { include?: readonly string[] }).include ?? [])\n .map(propKey => resolveIndexableColumn(collection, propKey, resolveColumnName, fail));\n const overlap = include.find(c => keys.some(k => k.column === c));\n if (overlap) fail(`\"${overlap}\" is in both \\`on\\` and \\`include\\`; Postgres rejects the overlap.`);\n\n if (unique && keys.length === 1) {\n const propKey = typeof index.on[0] === \"string\" ? index.on[0] as string : (index.on[0] as { prop: string }).prop;\n const property = collection.properties?.[propKey] as { validation?: { unique?: boolean } } | undefined;\n if (property?.validation?.unique) {\n fail(\n `\"${propKey}\" already declares \\`validation.unique\\`, which compiles to an inline UNIQUE. ` +\n `Two declarations of one guarantee — remove one.`\n );\n }\n }\n\n const predicate = index.where\n ? resolvePredicate(collection, index.where, resolveColumnName, fail)\n : null;\n\n const withoutName = { schema, table, method, unique, keys, include, predicate, reason: index.reason };\n const indexName = deriveIndexName(withoutName);\n\n const clash = byName.get(indexName);\n if (clash !== undefined) {\n fail(`derives the same name as indexes[${clash}] — they are the same index declared twice.`);\n }\n byName.set(indexName, position);\n\n specs.push({ ...withoutName, indexName });\n });\n\n return specs;\n};\n\n/**\n * Every declared index across a set of collections, in a stable order.\n *\n * Sorted because the result reaches `schema.sql`, which `doctor` string-\n * compares against a regenerated copy — `generatePostgresDdl` does not sort its\n * collections, so leaving this in declaration order would make the artifact\n * depend on the order files happened to load in.\n */\nexport const buildCollectionIndexPlan = (\n collections: readonly CollectionConfig[],\n resolveColumnName: ResolveColumnName\n): CollectionIndexSpec[] =>\n sortIndexSpecs(collections.flatMap(collection => buildCollectionIndexSpecs(collection, resolveColumnName)));\n\n/**\n * The stable order every consumer of a set of index specs uses.\n *\n * Exported because the boot-time diff reads the specs off the schema plan\n * rather than rebuilding them, and it has to reach the same order the CLI's\n * exclude list and `schema.sql` do — a second sort written out beside this one\n * is a second order the moment either is edited.\n */\nexport const sortIndexSpecs = (specs: readonly CollectionIndexSpec[]): CollectionIndexSpec[] =>\n [...specs].sort((a, b) =>\n a.schema.localeCompare(b.schema) ||\n a.table.localeCompare(b.table) ||\n a.indexName.localeCompare(b.indexName));\n\n// ── Foreign-key indexes ──────────────────────────────────────────────────────\n\n/**\n * The `reason` a derived foreign-key index carries. Never part of the name —\n * see {@link indexFingerprint} — so rewording it renames nothing.\n */\nexport const FOREIGN_KEY_INDEX_REASON =\n \"Derived for a foreign key: Postgres indexes the key a constraint points at, never the column holding it.\";\n\n/**\n * Whether an index already serves an equality lookup on `column` alone.\n *\n * A btree whose *leading* key is the column does, unique or not — that is the\n * prefix rule, and it is why a composite `(author_id, created_at)` makes a\n * second index on `author_id` pure write amplification. A partial index does\n * not: it serves only the rows its predicate admits, and a foreign-key lookup\n * has to reach every row. Nor does GIN or BRIN, which answer different\n * questions than \"the rows whose key is one of these\".\n */\nexport const leadsWithColumn = (spec: Pick<CollectionIndexSpec, \"method\" | \"predicate\" | \"keys\">, column: string): boolean =>\n spec.method === \"btree\" && spec.predicate === null && spec.keys[0]?.column === column;\n\n/**\n * The btree a foreign-key column gets when nothing else already leads with it.\n *\n * Postgres creates the index a foreign key *references* (the target's primary\n * key) and never the one on the column *holding* it. Every read from the other\n * side of the link filters on that column — a `hasMany`/`hasOne` include, a\n * nested listing (`/authors/5/posts`, page and count), the reverse side of a\n * many-to-many — and so does the `ON DELETE` check when a target row goes. With\n * no index each of those is a sequential scan of the child table: measured at\n * 13 ms for 25 parents over 100k children, and about 250 ms per nested listing\n * at a million.\n *\n * Named by {@link deriveIndexName} like every other index, so it is a\n * Rebase-managed name (`_ix_<fingerprint>`), it is in the Atlas diff, and it\n * is byte-for-byte the name an author's own plain index on the column would\n * derive. That identity is what makes the derived index and a declared one the\n * same object rather than two.\n */\nexport const foreignKeyIndexSpec = (schema: string, table: string, column: string): CollectionIndexSpec => {\n const withoutName = {\n schema,\n table,\n method: \"btree\" as const,\n unique: false,\n keys: [{ column, direction: \"asc\" as const, nulls: \"last\" as const }],\n include: [],\n predicate: null,\n reason: FOREIGN_KEY_INDEX_REASON\n };\n return { ...withoutName, indexName: deriveIndexName(withoutName), derived: \"foreign-key\" };\n};\n","/**\n * The names `db push` hands Atlas's `--exclude`, spelled so they match.\n *\n * An exclude is the only thing between `atlas schema apply --auto-approve` and\n * an object Rebase does not own: a table no collection backs, a hand-written\n * index, a CHECK constraint, the search and vector columns Rebase applies\n * itself. Atlas reads each one as a glob split on `.`, so a name is not a\n * pattern as it stands. Measured against the pinned 1.2.3:\n *\n * - a `.` in a name makes one more part, and Atlas refuses the whole command,\n * `too many parts in pattern` — so every push fails on that database;\n * - `[`, `]`, `*` and `?` are glob syntax. `[v1]` is a class matching `v` or\n * `1`, so `idx[v1]` matches `idxv` and not the index called `idx[v1]`:\n * nothing is excluded, nothing is reported, and Atlas plans the drop. For\n * an index that drop is not gated, so it applied without a word.\n *\n * So each part is escaped on its own and the parts are joined: a `.` becomes\n * `?`, which matches it (and any one character, so a pattern that also keeps a\n * near-namesake errs on the side of keeping), and glob syntax is escaped with\n * `\\`, which Atlas reads as the literal.\n *\n * Code that reads these patterns back — the migration stripper, the generated\n * column ownership check, the index ownership check — reads them with\n * {@link excludePatternParts}, the exact inverse for a pattern built here.\n */\n\n/** One part of an Atlas `--exclude` pattern that matches exactly this name. */\nexport function atlasExcludeSegment(name: string): string {\n return name.replace(/[\\\\*?[\\]]/g, ch => `\\\\${ch}`).replace(/\\./g, \"?\");\n}\n\n/**\n * The pattern that matches exactly the object these names qualify:\n * `(schema, table)` for a table, `(schema, table, object)` for a column, an\n * index or a constraint. Three parts for anything on a table: a two-part\n * pattern reads as a table, matches nothing, and reports no error.\n */\nexport function atlasExcludePattern(...parts: string[]): string {\n return parts.map(atlasExcludeSegment).join(\".\");\n}\n\n/**\n * The names a pattern from {@link atlasExcludePattern} was built from, or\n * `undefined` for one that is not a plain name — a wildcard such as `auth.*`.\n *\n * Exact for every pattern built there: a `\\` escapes the character after it,\n * and an unescaped `?` can only be a dot.\n */\nexport function excludePatternParts(pattern: string): string[] | undefined {\n const parts: string[] = [];\n for (const segment of pattern.split(\".\")) {\n let name = \"\";\n for (let i = 0; i < segment.length; i++) {\n const ch = segment[i];\n if (ch === \"\\\\\" && i + 1 < segment.length) {\n name += segment[++i];\n } else if (ch === \"?\") {\n name += \".\";\n } else if (ch === \"*\" || ch === \"[\" || ch === \"]\") {\n return undefined;\n } else {\n name += ch;\n }\n }\n parts.push(name);\n }\n return parts;\n}\n","/**\n * Terminal output for the `rebase db|schema|doctor` commands.\n *\n * These commands used to write every line through `logger`, and that is a\n * category error with three separate consequences:\n *\n * - `logger` prefixes each line with its own level, so a box-drawn report\n * arrived as `ℹ️ [INFO] ┌─ ✗ Missing Column ───` and the frame no longer\n * lined up with anything;\n * - `logger` is gated by `LOG_LEVEL`, which ships in the scaffold's own\n * `.env.example` — a developer who quietened their dev server with\n * `LOG_LEVEL=warn` got a `rebase db push` that printed almost nothing and\n * still exited non-zero, indistinguishable from a crash;\n * - under `NODE_ENV=production` `logger` emits JSON, so the whole report\n * became log records with the chalk escape codes embedded in them.\n *\n * A CLI's report *is* its return value. It goes to the terminal unconditionally\n * and unadorned. `packages/cli` has always written its output this way; this is\n * the same three functions for the plugin CLI that `rebase` delegates to.\n *\n * `logger` still belongs in this package's *runtime* — a request handler has no\n * terminal and its lines want levels, timestamps and redaction. The rule is the\n * caller, not the severity: anything a developer reads because they typed a\n * command goes here, anything a server emits while running goes to `logger`.\n *\n * Errors and warnings go to stderr so `rebase db push > plan.txt` keeps the\n * diagnosis on the terminal where it is readable.\n */\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\n/** One line of human-facing output on stdout. */\nexport const out = (line = \"\"): void => {\n console.log(line);\n};\n\n/** One line of human-facing warning output on stderr. */\nexport const outWarn = (line = \"\"): void => {\n console.warn(line);\n};\n\n/** One line of human-facing error output on stderr. */\nexport const outError = (line = \"\"): void => {\n console.error(line);\n};\n\n/**\n * Whether a failure should be printed with its stack — `rebase --debug`, which\n * the launcher passes down as `REBASE_DEBUG`, or `REBASE_DEBUG` set by hand.\n */\nexport const wantsStack = (): boolean => parseEnvBoolean(process.env.REBASE_DEBUG) === true;\n\n/**\n * An error as a person reads it: its message, and its stack only under\n * `--debug`.\n *\n * The rule `rebase` itself follows (`bin/rebase.js`). These commands run in a\n * child process the launcher's handler never sees, so a syntax error in a\n * collection file reached the terminal as `Doctor failed CollectionConfigError:`\n * followed by twenty frames of loader internals, under a sentence that already\n * said which file and which line.\n */\nexport const describeFailure = (error: unknown): string => {\n if (!(error instanceof Error)) return String(error);\n const failedQuery = describeFailedQuery(error);\n const lead = failedQuery?.reason ? `${failedQuery.reason}\\n ` : \"\";\n if (wantsStack() && error.stack) {\n if (!failedQuery) return error.stack;\n // The stack opens with the message, `params:` line and all.\n const opening = `${error.name}: ${error.message}`;\n const frames = error.stack.startsWith(opening) ? error.stack.slice(opening.length) : `\\n${error.stack}`;\n return `${lead}${error.name}: ${failedQuery.query}${frames}`;\n }\n if (failedQuery) return `${lead}${failedQuery.query}\\n Re-run with --debug for the stack trace.`;\n return `${error.message}\\n Re-run with --debug for the stack trace.`;\n};\n\n/**\n * A failed query as a reader needs it: why it failed — Postgres' own reason\n * with its SQLSTATE (`relation \"nope_table\" does not exist (42P01)`), or the\n * driver's when Postgres never answered — and the query without the values it\n * ran with. `null` for any other error.\n *\n * Drizzle reports a failed query as `Failed query: <sql>` and a `params:` line\n * and keeps the error underneath in `cause`, so the message alone names a query\n * and no reason: `rebase console -e` printed exactly that, `--debug` included.\n * The values stay off the terminal: they are whatever the code passed, a\n * password hash or a token as readily as an id.\n */\nfunction describeFailedQuery(error: Error): { reason: string | null; query: string } | null {\n if (!error.message.startsWith(\"Failed query:\")) return null;\n const paramsAt = error.message.lastIndexOf(\"\\nparams:\");\n const postgres = postgresError(error.cause);\n return {\n reason: postgres ? `${postgres.message} (${postgres.code})` : deepestMessage(error.cause),\n query: paramsAt === -1 ? error.message : error.message.slice(0, paramsAt)\n };\n}\n\n/** The error Postgres raised, from a cause chain: the one carrying a SQLSTATE. */\nfunction postgresError(cause: unknown, depth = 0): { code: string; message: string } | null {\n if (!(cause instanceof Error) || depth > 5) return null;\n if (\"code\" in cause && typeof cause.code === \"string\" && /^[0-9A-Z]{5}$/.test(cause.code) && cause.message) {\n return { code: cause.code, message: cause.message };\n }\n return postgresError(cause.cause, depth + 1);\n}\n\n/** The innermost message in a cause chain, or `null` when there is none. */\nfunction deepestMessage(cause: unknown, depth = 0): string | null {\n if (!(cause instanceof Error) || depth > 5) return null;\n return deepestMessage(cause.cause, depth + 1) ?? (cause.message || null);\n}\n","const ANSI_BACKGROUND_OFFSET = 10;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u001B[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u001B[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u001B[${38 + offset};2;${red};${green};${blue}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u001B[${style[0]}m`,\n\t\t\t\tclose: `\\u001B[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\tcodes.set(style[0], style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u001B[39m';\n\tstyles.bgColor.close = '\\u001B[49m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[a-f\\d]{6}|[a-f\\d]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n","import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\n/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\nfunction envForceColor() {\n\tif ('FORCE_COLOR' in env) {\n\t\tif (env.FORCE_COLOR === 'true') {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (env.FORCE_COLOR === 'false') {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-ghostty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'wezterm') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n","// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.\nexport function stringReplaceAll(string, substring, replacer) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + replacer;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst gotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n","import ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\nimport { // eslint-disable-line import/order\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\n\n// `supportsColor.level` → `ansiStyles.color[name]` mapping\nconst levelMapping = [\n\t'ansi',\n\t'ansi',\n\t'ansi256',\n\t'ansi16m',\n];\n\nconst styles = Object.create(null);\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {\n\t\tthrow new Error('The `level` option should be an integer from 0 to 3');\n\t}\n\n\t// Detect level if not set manually\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject.level = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\nconst getModelAnsi = (model, level, type, ...arguments_) => {\n\tif (model === 'rgb') {\n\t\tif (level === 'ansi16m') {\n\t\t\treturn ansiStyles[type].ansi16m(...arguments_);\n\t\t}\n\n\t\tif (level === 'ansi256') {\n\t\t\treturn ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));\n\t\t}\n\n\t\treturn ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));\n\t}\n\n\tif (model === 'hex') {\n\t\treturn getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));\n\t}\n\n\treturn ansiStyles[type][model](...arguments_);\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tstyles[model] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n\n\tconst bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);\n\tstyles[bgModel] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n}\n\nconst proto = Object.defineProperties(() => {}, {\n\t...styles,\n\tlevel: {\n\t\tenumerable: true,\n\t\tget() {\n\t\t\treturn this[GENERATOR].level;\n\t\t},\n\t\tset(level) {\n\t\t\tthis[GENERATOR].level = level;\n\t\t},\n\t},\n});\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\t// eslint-disable-next-line no-implicit-coercion\n\tconst builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\tbuilder[GENERATOR] = self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\tif (self.level <= 0 || !string) {\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u001B')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\nObject.defineProperties(createChalk.prototype, styles);\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n"],"x_google_ignoreList":[3,4,5,6],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  __createRequire(import.meta.url);
3
- import { n as __exportAll } from "./rolldown-runtime-V7rFbMRe.js";
3
+ import { i as __exportAll } from "./cli-prompt-DXG0yk-h.js";
4
4
  import { isPostgresCollectionConfig } from "@rebasepro/types";
5
5
  import { getTableName } from "@rebasepro/common";
6
6
  import { toPostgresIdentifier } from "@rebasepro/utils";
@@ -295,4 +295,4 @@ $rebase_vector$;`;
295
295
  //#endregion
296
296
  export { vectorDimensionGuard as a, vectorExtensionStatement as c, vectorIndexStatements as d, vector_index_exports as f, vectorColumnDefinition as i, vectorIndexNames as l, buildVectorColumnSpecs as n, vectorExtensionDeclared as o, buildVectorIndexPlan as r, vectorExtensionHint as s, VECTOR_EXTENSION_OPT_IN as t, vectorIndexStatement as u };
297
297
 
298
- //# sourceMappingURL=vector-index-BFhyEaiz.js.map
298
+ //# sourceMappingURL=vector-index-DsQ3V2d2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vector-index-BFhyEaiz.js","names":[],"sources":["../src/schema/vector-index.ts"],"sourcesContent":["/**\n * The one place a `{ type: \"vector\" }` property becomes an ANN index.\n *\n * Without an index, pgvector answers `ORDER BY embedding <=> $1` by computing\n * the distance to every row and sorting — exact, and linear. That is the right\n * answer at ten thousand rows and the wrong one at a million, which is why the\n * default here is to build an index rather than to leave the column bare.\n *\n * ## The operator class is not a detail\n *\n * An index is built for exactly one operator class, and the planner uses it\n * only for the operator that class implements. `vector_cosine_ops` answers\n * `<=>` and nothing else; a query asking for `<->` against a cosine index gets\n * a sequential scan and no error. So the default indexed distance here is\n * `cosine`, because `cosine` is what `vectorSearch` measures with when the\n * caller does not say — see `DrizzleConditionBuilder.buildVectorSearch`. The\n * two defaults have to agree, and this comment is the reason they do.\n *\n * ## Why 2000 dimensions is a ceiling and not an error\n *\n * pgvector cannot index a `vector` wider than 2000 dimensions with either\n * method. A 3072-dimension embedding (`text-embedding-3-large`) is therefore\n * storable and searchable but not indexable. Refusing the boot over that would\n * make a working configuration unbootable; silently indexing it is impossible.\n * So the column is created, the index is skipped, and the reason is reported.\n *\n * Like `search-column.ts`, this module exists so that the DDL generator and the\n * boot-time ensure render the *same* specification rather than describing the\n * same index twice, differently. `contracts/derived-names.txt` records the\n * names both produce, and CI fails if they diverge.\n *\n * ## And why the column itself is described here too\n *\n * `VECTOR(n)` is a type Atlas cannot be shown. It has to materialise the\n * desired state in a dev database to diff against, that database is created\n * empty and *emptied again* by Atlas at the start of every run, and nothing in\n * the free tier can put `CREATE EXTENSION vector` back — so a `schema.sql`\n * mentioning the type fails with `type \"vector\" does not exist` on every push,\n * for good. Search hit the same wall for its own reasons and took the same way\n * out: the objects leave `schema.sql`, Atlas is told to exclude them, and\n * Rebase applies them itself. See `generatePostgresVectorDdl`.\n */\nimport type { CollectionConfig, Property, VectorDistance, VectorIndexConfig } from \"@rebasepro/types\";\nimport { isPostgresCollectionConfig } from \"@rebasepro/types\";\nimport { getTableName } from \"@rebasepro/common\";\nimport { toPostgresIdentifier } from \"@rebasepro/utils\";\n\n/**\n * The widest `vector` pgvector will build an HNSW or IVFFlat index over.\n * Storage and exact search are unaffected by this limit.\n */\nexport const MAX_INDEXABLE_VECTOR_DIMENSIONS = 2000;\n\n/** The distance indexed when a property does not name one. */\nexport const DEFAULT_VECTOR_DISTANCE: VectorDistance = \"cosine\";\n\n/** The index method used when a property does not name one. */\nexport const DEFAULT_VECTOR_INDEX_METHOD = \"hnsw\" as const;\n\n/**\n * Operator class per distance. These strings are part of the database contract:\n * they appear in `CREATE INDEX`, so renaming one renames an index.\n */\nconst OPERATOR_CLASS: Record<VectorDistance, string> = {\n cosine: \"vector_cosine_ops\",\n l2: \"vector_l2_ops\",\n inner_product: \"vector_ip_ops\"\n};\n\n/** Short, stable tag per distance, used to name the index. */\nconst DISTANCE_TAG: Record<VectorDistance, string> = {\n cosine: \"cosine\",\n l2: \"l2\",\n inner_product: \"ip\"\n};\n\nexport interface VectorIndexSpec {\n schema: string;\n table: string;\n column: string;\n indexName: string;\n method: \"hnsw\" | \"ivfflat\";\n distance: VectorDistance;\n operatorClass: string;\n /** Rendered into `WITH (...)`; empty when every parameter is defaulted. */\n parameters: Array<[string, number]>;\n}\n\n/** A vector column that will not be indexed, and why. */\nexport interface SkippedVectorIndex {\n schema: string;\n table: string;\n column: string;\n dimensions: number;\n reason: string;\n}\n\nexport interface VectorIndexPlan {\n specs: VectorIndexSpec[];\n skipped: SkippedVectorIndex[];\n}\n\nexport class VectorIndexConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VectorIndexConfigError\";\n }\n}\n\nconst isVectorProperty = (prop: unknown): prop is Property & {\n type: \"vector\";\n dimensions: number;\n index?: VectorIndexConfig | false;\n} => !!prop && typeof prop === \"object\" && (prop as { type?: string }).type === \"vector\";\n\nconst asDistances = (config: VectorIndexConfig, label: string): VectorDistance[] => {\n const raw = config.distance ?? DEFAULT_VECTOR_DISTANCE;\n const list = Array.isArray(raw) ? raw : [raw];\n if (list.length === 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.distance\\` is an empty array. Name at least one distance, or set \\`index: false\\` to create no index.`\n );\n }\n const seen = new Set<VectorDistance>();\n for (const distance of list) {\n if (!(distance in OPERATOR_CLASS)) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.distance\\` is \"${distance}\", which is not a pgvector distance. Use ${Object.keys(OPERATOR_CLASS).map(d => `\"${d}\"`).join(\", \")}.`\n );\n }\n if (seen.has(distance)) {\n throw new VectorIndexConfigError(`${label}: \\`index.distance\\` lists \"${distance}\" twice.`);\n }\n seen.add(distance);\n }\n return list;\n};\n\nconst assertPositiveInteger = (value: number | undefined, key: string, label: string): void => {\n if (value === undefined) return;\n if (!Number.isInteger(value) || value <= 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.${key}\\` is ${JSON.stringify(value)}. It must be a positive integer.`\n );\n }\n};\n\n/**\n * Index parameters for one method. Parameters belonging to the *other* method\n * are rejected rather than ignored, because a silently dropped `lists` on an\n * HNSW index reads, from the config, exactly like a tuned index.\n */\nconst parametersFor = (\n method: \"hnsw\" | \"ivfflat\",\n config: VectorIndexConfig,\n label: string\n): Array<[string, number]> => {\n assertPositiveInteger(config.m, \"m\", label);\n assertPositiveInteger(config.efConstruction, \"efConstruction\", label);\n assertPositiveInteger(config.lists, \"lists\", label);\n\n if (method === \"hnsw\") {\n if (config.lists !== undefined) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.lists\\` only applies to \\`method: \"ivfflat\"\\`. Remove it, or switch the method.`\n );\n }\n const params: Array<[string, number]> = [];\n if (config.m !== undefined) params.push([\"m\", config.m]);\n if (config.efConstruction !== undefined) params.push([\"ef_construction\", config.efConstruction]);\n return params;\n }\n\n for (const key of [\"m\", \"efConstruction\"] as const) {\n if (config[key] !== undefined) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.${key}\\` only applies to \\`method: \"hnsw\"\\`. Remove it, or switch the method.`\n );\n }\n }\n return config.lists !== undefined ? [[\"lists\", config.lists]] : [];\n};\n\n/**\n * Every ANN index a collection's vector properties call for.\n *\n * `resolveColumn` is passed in rather than imported so that this module stays\n * free of the DDL generator, which imports *it*. Both callers hand it the same\n * `resolveColumnName`, and a contract test asserts the names agree.\n */\nexport const buildVectorIndexPlan = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): VectorIndexPlan => {\n const specs: VectorIndexSpec[] = [];\n const skipped: SkippedVectorIndex[] = [];\n const properties = collection.properties ?? {};\n\n const table = getTableName(collection);\n const schema = isPostgresCollectionConfig(collection) && collection.schema ? collection.schema : \"public\";\n\n for (const [propName, prop] of Object.entries(properties)) {\n if (!isVectorProperty(prop)) continue;\n if (prop.index === false) continue;\n\n const label = `${collection.slug}.${propName}`;\n const column = resolveColumn(propName, prop as Property);\n const config: VectorIndexConfig = prop.index ?? {};\n const method = config.method ?? DEFAULT_VECTOR_INDEX_METHOD;\n\n if (method !== \"hnsw\" && method !== \"ivfflat\") {\n throw new VectorIndexConfigError(\n `${label}: \\`index.method\\` is \"${method}\". Use \"hnsw\" or \"ivfflat\".`\n );\n }\n\n // Read before the dimension gate so a malformed block is reported even\n // on a column too wide to index — the config is wrong either way.\n const distances = asDistances(config, label);\n const parameters = parametersFor(method, config, label);\n\n if (!Number.isInteger(prop.dimensions) || prop.dimensions <= 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`dimensions\\` is ${JSON.stringify(prop.dimensions)}. It must be a positive integer.`\n );\n }\n\n if (prop.dimensions > MAX_INDEXABLE_VECTOR_DIMENSIONS) {\n skipped.push({\n schema,\n table,\n column,\n dimensions: prop.dimensions,\n reason:\n `pgvector cannot index a vector wider than ${MAX_INDEXABLE_VECTOR_DIMENSIONS} dimensions, and ` +\n `${label} declares ${prop.dimensions}. The column works and \\`vectorSearch\\` still answers, as an ` +\n `exact scan. To index it, reduce the dimensions (many embedding models support a shorter output) ` +\n `or set \\`index: false\\` to state that the scan is intended.`\n });\n continue;\n }\n\n for (const distance of distances) {\n specs.push({\n schema,\n table,\n column,\n // Distance is in the name because one column may carry an index\n // per distance, and two indexes cannot share a name. The method\n // is in it because switching methods is a different index, not\n // a redefinition of the same one — `CREATE INDEX IF NOT EXISTS`\n // would otherwise keep the old one and report success.\n indexName: toPostgresIdentifier(`${table}_${column}_${method}_${DISTANCE_TAG[distance]}`),\n method,\n distance,\n operatorClass: OPERATOR_CLASS[distance],\n parameters\n });\n }\n }\n\n return { specs, skipped };\n};\n\n/**\n * The `CREATE INDEX` for one spec.\n *\n * `CONCURRENTLY` is deliberately absent, for the same reason it is absent from\n * `searchIndexStatements`: this form is replayed as part of a migration, where\n * a concurrent build is not allowed. The boot-time ensure rewrites it — see\n * `ensureCollectionTables`.\n */\nexport const vectorIndexStatement = (spec: VectorIndexSpec): string => {\n const params = spec.parameters.length\n ? ` WITH (${spec.parameters.map(([key, value]) => `${key} = ${value}`).join(\", \")})`\n : \"\";\n return (\n `CREATE INDEX IF NOT EXISTS \"${spec.indexName}\" ON \"${spec.schema}\".\"${spec.table}\" ` +\n `USING ${spec.method} (\"${spec.column}\" ${spec.operatorClass})${params};`\n );\n};\n\n/** Every statement for a plan, in a stable order. */\nexport const vectorIndexStatements = (plan: VectorIndexPlan): string[] =>\n plan.specs.map(vectorIndexStatement);\n\n/** The index names a plan creates — what the derived-names contract records. */\nexport const vectorIndexNames = (plan: VectorIndexPlan): string[] =>\n plan.specs.map(spec => spec.indexName);\n\n// ── The column, for the file Rebase applies itself ──────────────────────────\n\nconst quote = (v: string): string => `'${v.replace(/'/g, \"''\")}'`;\n\n/**\n * The schema pgvector's types are installed into.\n *\n * `WITH SCHEMA public` for the same load-bearing reason `searchExtensionStatements`\n * gives: an unqualified `CREATE EXTENSION` lands in the first schema on\n * `search_path`, which is `\"$user\", public` — and the scaffold's role is named\n * `rebase`, the same as a schema the generator creates. Left to itself the\n * extension would install into `rebase`, and every unqualified `VECTOR(n)`\n * below would fail to resolve.\n */\nexport const VECTOR_EXTENSION_SCHEMA = \"public\";\n\n/** The extension name a database has to name to let Rebase install pgvector. */\nexport const VECTOR_EXTENSION = \"vector\";\n\n/**\n * How a project says Rebase may install pgvector, quoted into the messages that\n * have to name it. Spelled once so the option and the advice cannot drift.\n */\nexport const VECTOR_EXTENSION_OPT_IN = `database({ extensions: [\"${VECTOR_EXTENSION}\"] })`;\n\n/** Did the project give Rebase leave to install pgvector? */\nexport const vectorExtensionDeclared = (extensions: readonly string[] | undefined): boolean =>\n (extensions ?? []).includes(VECTOR_EXTENSION);\n\n/**\n * Install pgvector — emitted only when the database asked for it.\n *\n * Opt-in because installing an extension is a decision with a deployment behind\n * it: the image has to ship the library, the role has to be allowed to install\n * it, and a managed provider has to have it on an allow-list. None of that is\n * visible from inside the connection, so Rebase does not decide it. See\n * `DatabaseOptions.extensions`.\n *\n * Withholding the statement is not withholding the *column*: the column is\n * still created, and Postgres refuses it with `type \"vector\" does not exist`\n * on a database where pgvector was never installed by hand. That error is the\n * one this design accepts, and `vectorExtensionHint` is what makes it name\n * {@link VECTOR_EXTENSION_OPT_IN} rather than nothing.\n */\nexport const vectorExtensionStatement = (): string =>\n `CREATE EXTENSION IF NOT EXISTS ${VECTOR_EXTENSION} WITH SCHEMA ${VECTOR_EXTENSION_SCHEMA};`;\n\n/**\n * The missing-pgvector explanation, appended to whichever error revealed it.\n *\n * Two readers, needing opposite things, which is why the branch is on the error\n * text rather than on the configuration:\n *\n * - **`type \"vector\" does not exist`** — nobody opted in and the database has\n * no pgvector. The fix is one line of config they cannot guess, so naming\n * the option *is* the hint.\n * - **the install itself failed** — the config is already right, and repeating\n * the option would send them to edit a correct line. What is missing is the\n * library on the server, or the grant.\n *\n * Lives here rather than beside either caller because both need it: the boot\n * ensure raises the first through its action applier, and `rebase db push`\n * raises it out of `applyVectorDdl`. A hint on only one path is how a bare\n * `type \"vector\" does not exist` reaches somebody — which is the thing this\n * exists to prevent.\n */\nexport const vectorExtensionHint = (message: string): string => {\n const installRefused = /extension \"vector\" is not available/i.test(message)\n || /(permission denied to create extension|must be (superuser|owner).{0,40}extension)/i.test(message);\n if (installRefused) {\n return (\n \"\\n pgvector was declared and could not be installed. It is a server extension, so it needs an image \" +\n \"that ships the library (the scaffold's `pgvector/pgvector:pg18` does; a stock `postgres:18` does not) \" +\n \"and a role allowed to run `CREATE EXTENSION vector;`. Managed Postgres usually allows it once the \" +\n \"extension is on the provider's allow-list.\"\n );\n }\n if (!/type \"(vector|halfvec|sparsevec)\" does not exist/i.test(message)) return \"\";\n return (\n \"\\n pgvector is not installed on this database, and Rebase installs it only where a database says it may: \" +\n `add \\`${VECTOR_EXTENSION_OPT_IN}\\` in config/resources.ts, or install it once by hand with ` +\n \"`CREATE EXTENSION vector;`. Either way the server needs an image that ships the library — the scaffold's \" +\n \"`pgvector/pgvector:pg18` does, a stock `postgres:18` does not. Rebase then creates the column and its ANN \" +\n \"index automatically — see the `index` option on the property.\"\n );\n};\n\n/** One `{ type: \"vector\" }` property, as a column. */\nexport interface VectorColumnSpec {\n schema: string;\n table: string;\n column: string;\n dimensions: number;\n /** Rendered after the type, in the generator's order: UNIQUE then NOT NULL. */\n modifiers: string;\n}\n\n/**\n * Every vector column a collection declares.\n *\n * Wider than {@link buildVectorIndexPlan} on purpose: that one answers \"what\n * gets an ANN index\", and skips both a property with `index: false` and one too\n * wide to index. Either still needs its column.\n */\nexport const buildVectorColumnSpecs = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): VectorColumnSpec[] => {\n const table = getTableName(collection);\n const schema = isPostgresCollectionConfig(collection) && collection.schema ? collection.schema : \"public\";\n const specs: VectorColumnSpec[] = [];\n\n for (const [propName, prop] of Object.entries(collection.properties ?? {})) {\n if (!isVectorProperty(prop)) continue;\n // Assembled in the CREATE TABLE generator's order, so the column this\n // file adds and the column `schema.sql` used to declare are the same\n // column. A vector property is never a primary key and carries no\n // SQL-level default, which is what leaves only these two.\n const validation = (prop as { validation?: { required?: boolean; unique?: boolean } }).validation;\n let modifiers = \"\";\n if (validation?.unique) modifiers += \" UNIQUE\";\n if (validation?.required) modifiers += \" NOT NULL\";\n specs.push({\n schema,\n table,\n column: resolveColumn(propName, prop as Property),\n dimensions: prop.dimensions,\n modifiers\n });\n }\n\n return specs;\n};\n\n/** The column type — the one place `VECTOR(n)` is spelled. */\nexport const vectorColumnType = (spec: Pick<VectorColumnSpec, \"dimensions\">): string =>\n `VECTOR(${spec.dimensions})`;\n\n/** The column definition as it appears inside `CREATE TABLE`. */\nexport const vectorColumnDefinition = (spec: VectorColumnSpec): string =>\n `\"${spec.column}\" ${vectorColumnType(spec)}${spec.modifiers}`;\n\n/**\n * Refuse — or perform — a `dimensions` change that `ADD COLUMN IF NOT EXISTS`\n * would otherwise swallow.\n *\n * Without this the file *launders* the change: the ADD is a no-op against a\n * column that exists, so a project that went from 384 to 768 dimensions would\n * push clean, keep a 384-wide column, and fail on the next insert with a\n * message about the row rather than about the config. Atlas used to catch this\n * — it owned the column and planned the `ALTER … TYPE` — and taking the column\n * out of its sight is exactly what makes the guard necessary.\n *\n * The widening is performed when the column holds no values, because that is\n * the case Atlas handled and it is the common one: a developer changing\n * embedding models before there are any embeddings. With values present the\n * conversion is pgvector's to reject — every stored vector is the old width —\n * so this refuses first and names the statement to run afterwards.\n *\n * `atttypmod` on a `vector` column *is* the dimension count: pgvector stores it\n * directly rather than offsetting it the way `varchar` does. `-1` means the\n * column was declared as a bare `vector`, which is drift in the same sense.\n */\nexport const vectorDimensionGuard = (spec: VectorColumnSpec): string => {\n const relation = `\"${spec.schema}\".\"${spec.table}\"`;\n return `DO $rebase_vector$\nDECLARE actual int;\nBEGIN\n SELECT a.atttypmod INTO actual\n FROM pg_attribute a\n JOIN pg_type t ON t.oid = a.atttypid\n WHERE a.attrelid = ${quote(relation)}::regclass\n AND a.attname = ${quote(spec.column)}\n AND NOT a.attisdropped\n AND t.typname = 'vector';\n IF actual IS NOT NULL AND actual <> ${spec.dimensions} THEN\n IF EXISTS (SELECT 1 FROM ${relation} WHERE \"${spec.column}\" IS NOT NULL) THEN\n RAISE EXCEPTION 'Rebase: ${spec.schema}.${spec.table}.\"${spec.column}\" declares ${spec.dimensions} dimensions but the column is vector(%), and it already holds values of the old width. pgvector cannot convert them. Re-embed the rows at ${spec.dimensions} dimensions (or clear the column), then re-apply: ALTER TABLE ${relation} ALTER COLUMN \"${spec.column}\" TYPE ${vectorColumnType(spec)};', actual;\n END IF;\n ALTER TABLE ${relation} ALTER COLUMN \"${spec.column}\" TYPE ${vectorColumnType(spec)};\n END IF;\nEND\n$rebase_vector$;`;\n};\n\n/**\n * The object names a collection's vector properties own, unqualified.\n *\n * What Atlas has to be told to exclude. Only the column and the ANN indexes: a\n * `UNIQUE` or `NOT NULL` on the column is a property *of* the column, and\n * excluding the column takes them with it — measured against Atlas 1.2.3 and\n * 1.3.2, where a target carrying `vector(3) NOT NULL UNIQUE` and a `schema.sql`\n * carrying neither reported \"Schema is synced, no changes to be made\".\n */\nexport const vectorObjectNames = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): string[] => [\n ...buildVectorColumnSpecs(collection, resolveColumn).map(spec => spec.column),\n ...vectorIndexNames(buildVectorIndexPlan(collection, resolveColumn))\n];\n"],"mappings":"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"}
1
+ {"version":3,"file":"vector-index-DsQ3V2d2.js","names":[],"sources":["../src/schema/vector-index.ts"],"sourcesContent":["/**\n * The one place a `{ type: \"vector\" }` property becomes an ANN index.\n *\n * Without an index, pgvector answers `ORDER BY embedding <=> $1` by computing\n * the distance to every row and sorting — exact, and linear. That is the right\n * answer at ten thousand rows and the wrong one at a million, which is why the\n * default here is to build an index rather than to leave the column bare.\n *\n * ## The operator class is not a detail\n *\n * An index is built for exactly one operator class, and the planner uses it\n * only for the operator that class implements. `vector_cosine_ops` answers\n * `<=>` and nothing else; a query asking for `<->` against a cosine index gets\n * a sequential scan and no error. So the default indexed distance here is\n * `cosine`, because `cosine` is what `vectorSearch` measures with when the\n * caller does not say — see `DrizzleConditionBuilder.buildVectorSearch`. The\n * two defaults have to agree, and this comment is the reason they do.\n *\n * ## Why 2000 dimensions is a ceiling and not an error\n *\n * pgvector cannot index a `vector` wider than 2000 dimensions with either\n * method. A 3072-dimension embedding (`text-embedding-3-large`) is therefore\n * storable and searchable but not indexable. Refusing the boot over that would\n * make a working configuration unbootable; silently indexing it is impossible.\n * So the column is created, the index is skipped, and the reason is reported.\n *\n * Like `search-column.ts`, this module exists so that the DDL generator and the\n * boot-time ensure render the *same* specification rather than describing the\n * same index twice, differently. `contracts/derived-names.txt` records the\n * names both produce, and CI fails if they diverge.\n *\n * ## And why the column itself is described here too\n *\n * `VECTOR(n)` is a type Atlas cannot be shown. It has to materialise the\n * desired state in a dev database to diff against, that database is created\n * empty and *emptied again* by Atlas at the start of every run, and nothing in\n * the free tier can put `CREATE EXTENSION vector` back — so a `schema.sql`\n * mentioning the type fails with `type \"vector\" does not exist` on every push,\n * for good. Search hit the same wall for its own reasons and took the same way\n * out: the objects leave `schema.sql`, Atlas is told to exclude them, and\n * Rebase applies them itself. See `generatePostgresVectorDdl`.\n */\nimport type { CollectionConfig, Property, VectorDistance, VectorIndexConfig } from \"@rebasepro/types\";\nimport { isPostgresCollectionConfig } from \"@rebasepro/types\";\nimport { getTableName } from \"@rebasepro/common\";\nimport { toPostgresIdentifier } from \"@rebasepro/utils\";\n\n/**\n * The widest `vector` pgvector will build an HNSW or IVFFlat index over.\n * Storage and exact search are unaffected by this limit.\n */\nexport const MAX_INDEXABLE_VECTOR_DIMENSIONS = 2000;\n\n/** The distance indexed when a property does not name one. */\nexport const DEFAULT_VECTOR_DISTANCE: VectorDistance = \"cosine\";\n\n/** The index method used when a property does not name one. */\nexport const DEFAULT_VECTOR_INDEX_METHOD = \"hnsw\" as const;\n\n/**\n * Operator class per distance. These strings are part of the database contract:\n * they appear in `CREATE INDEX`, so renaming one renames an index.\n */\nconst OPERATOR_CLASS: Record<VectorDistance, string> = {\n cosine: \"vector_cosine_ops\",\n l2: \"vector_l2_ops\",\n inner_product: \"vector_ip_ops\"\n};\n\n/** Short, stable tag per distance, used to name the index. */\nconst DISTANCE_TAG: Record<VectorDistance, string> = {\n cosine: \"cosine\",\n l2: \"l2\",\n inner_product: \"ip\"\n};\n\nexport interface VectorIndexSpec {\n schema: string;\n table: string;\n column: string;\n indexName: string;\n method: \"hnsw\" | \"ivfflat\";\n distance: VectorDistance;\n operatorClass: string;\n /** Rendered into `WITH (...)`; empty when every parameter is defaulted. */\n parameters: Array<[string, number]>;\n}\n\n/** A vector column that will not be indexed, and why. */\nexport interface SkippedVectorIndex {\n schema: string;\n table: string;\n column: string;\n dimensions: number;\n reason: string;\n}\n\nexport interface VectorIndexPlan {\n specs: VectorIndexSpec[];\n skipped: SkippedVectorIndex[];\n}\n\nexport class VectorIndexConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VectorIndexConfigError\";\n }\n}\n\nconst isVectorProperty = (prop: unknown): prop is Property & {\n type: \"vector\";\n dimensions: number;\n index?: VectorIndexConfig | false;\n} => !!prop && typeof prop === \"object\" && (prop as { type?: string }).type === \"vector\";\n\nconst asDistances = (config: VectorIndexConfig, label: string): VectorDistance[] => {\n const raw = config.distance ?? DEFAULT_VECTOR_DISTANCE;\n const list = Array.isArray(raw) ? raw : [raw];\n if (list.length === 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.distance\\` is an empty array. Name at least one distance, or set \\`index: false\\` to create no index.`\n );\n }\n const seen = new Set<VectorDistance>();\n for (const distance of list) {\n if (!(distance in OPERATOR_CLASS)) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.distance\\` is \"${distance}\", which is not a pgvector distance. Use ${Object.keys(OPERATOR_CLASS).map(d => `\"${d}\"`).join(\", \")}.`\n );\n }\n if (seen.has(distance)) {\n throw new VectorIndexConfigError(`${label}: \\`index.distance\\` lists \"${distance}\" twice.`);\n }\n seen.add(distance);\n }\n return list;\n};\n\nconst assertPositiveInteger = (value: number | undefined, key: string, label: string): void => {\n if (value === undefined) return;\n if (!Number.isInteger(value) || value <= 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.${key}\\` is ${JSON.stringify(value)}. It must be a positive integer.`\n );\n }\n};\n\n/**\n * Index parameters for one method. Parameters belonging to the *other* method\n * are rejected rather than ignored, because a silently dropped `lists` on an\n * HNSW index reads, from the config, exactly like a tuned index.\n */\nconst parametersFor = (\n method: \"hnsw\" | \"ivfflat\",\n config: VectorIndexConfig,\n label: string\n): Array<[string, number]> => {\n assertPositiveInteger(config.m, \"m\", label);\n assertPositiveInteger(config.efConstruction, \"efConstruction\", label);\n assertPositiveInteger(config.lists, \"lists\", label);\n\n if (method === \"hnsw\") {\n if (config.lists !== undefined) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.lists\\` only applies to \\`method: \"ivfflat\"\\`. Remove it, or switch the method.`\n );\n }\n const params: Array<[string, number]> = [];\n if (config.m !== undefined) params.push([\"m\", config.m]);\n if (config.efConstruction !== undefined) params.push([\"ef_construction\", config.efConstruction]);\n return params;\n }\n\n for (const key of [\"m\", \"efConstruction\"] as const) {\n if (config[key] !== undefined) {\n throw new VectorIndexConfigError(\n `${label}: \\`index.${key}\\` only applies to \\`method: \"hnsw\"\\`. Remove it, or switch the method.`\n );\n }\n }\n return config.lists !== undefined ? [[\"lists\", config.lists]] : [];\n};\n\n/**\n * Every ANN index a collection's vector properties call for.\n *\n * `resolveColumn` is passed in rather than imported so that this module stays\n * free of the DDL generator, which imports *it*. Both callers hand it the same\n * `resolveColumnName`, and a contract test asserts the names agree.\n */\nexport const buildVectorIndexPlan = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): VectorIndexPlan => {\n const specs: VectorIndexSpec[] = [];\n const skipped: SkippedVectorIndex[] = [];\n const properties = collection.properties ?? {};\n\n const table = getTableName(collection);\n const schema = isPostgresCollectionConfig(collection) && collection.schema ? collection.schema : \"public\";\n\n for (const [propName, prop] of Object.entries(properties)) {\n if (!isVectorProperty(prop)) continue;\n if (prop.index === false) continue;\n\n const label = `${collection.slug}.${propName}`;\n const column = resolveColumn(propName, prop as Property);\n const config: VectorIndexConfig = prop.index ?? {};\n const method = config.method ?? DEFAULT_VECTOR_INDEX_METHOD;\n\n if (method !== \"hnsw\" && method !== \"ivfflat\") {\n throw new VectorIndexConfigError(\n `${label}: \\`index.method\\` is \"${method}\". Use \"hnsw\" or \"ivfflat\".`\n );\n }\n\n // Read before the dimension gate so a malformed block is reported even\n // on a column too wide to index — the config is wrong either way.\n const distances = asDistances(config, label);\n const parameters = parametersFor(method, config, label);\n\n if (!Number.isInteger(prop.dimensions) || prop.dimensions <= 0) {\n throw new VectorIndexConfigError(\n `${label}: \\`dimensions\\` is ${JSON.stringify(prop.dimensions)}. It must be a positive integer.`\n );\n }\n\n if (prop.dimensions > MAX_INDEXABLE_VECTOR_DIMENSIONS) {\n skipped.push({\n schema,\n table,\n column,\n dimensions: prop.dimensions,\n reason:\n `pgvector cannot index a vector wider than ${MAX_INDEXABLE_VECTOR_DIMENSIONS} dimensions, and ` +\n `${label} declares ${prop.dimensions}. The column works and \\`vectorSearch\\` still answers, as an ` +\n `exact scan. To index it, reduce the dimensions (many embedding models support a shorter output) ` +\n `or set \\`index: false\\` to state that the scan is intended.`\n });\n continue;\n }\n\n for (const distance of distances) {\n specs.push({\n schema,\n table,\n column,\n // Distance is in the name because one column may carry an index\n // per distance, and two indexes cannot share a name. The method\n // is in it because switching methods is a different index, not\n // a redefinition of the same one — `CREATE INDEX IF NOT EXISTS`\n // would otherwise keep the old one and report success.\n indexName: toPostgresIdentifier(`${table}_${column}_${method}_${DISTANCE_TAG[distance]}`),\n method,\n distance,\n operatorClass: OPERATOR_CLASS[distance],\n parameters\n });\n }\n }\n\n return { specs, skipped };\n};\n\n/**\n * The `CREATE INDEX` for one spec.\n *\n * `CONCURRENTLY` is deliberately absent, for the same reason it is absent from\n * `searchIndexStatements`: this form is replayed as part of a migration, where\n * a concurrent build is not allowed. The boot-time ensure rewrites it — see\n * `ensureCollectionTables`.\n */\nexport const vectorIndexStatement = (spec: VectorIndexSpec): string => {\n const params = spec.parameters.length\n ? ` WITH (${spec.parameters.map(([key, value]) => `${key} = ${value}`).join(\", \")})`\n : \"\";\n return (\n `CREATE INDEX IF NOT EXISTS \"${spec.indexName}\" ON \"${spec.schema}\".\"${spec.table}\" ` +\n `USING ${spec.method} (\"${spec.column}\" ${spec.operatorClass})${params};`\n );\n};\n\n/** Every statement for a plan, in a stable order. */\nexport const vectorIndexStatements = (plan: VectorIndexPlan): string[] =>\n plan.specs.map(vectorIndexStatement);\n\n/** The index names a plan creates — what the derived-names contract records. */\nexport const vectorIndexNames = (plan: VectorIndexPlan): string[] =>\n plan.specs.map(spec => spec.indexName);\n\n// ── The column, for the file Rebase applies itself ──────────────────────────\n\nconst quote = (v: string): string => `'${v.replace(/'/g, \"''\")}'`;\n\n/**\n * The schema pgvector's types are installed into.\n *\n * `WITH SCHEMA public` for the same load-bearing reason `searchExtensionStatements`\n * gives: an unqualified `CREATE EXTENSION` lands in the first schema on\n * `search_path`, which is `\"$user\", public` — and the scaffold's role is named\n * `rebase`, the same as a schema the generator creates. Left to itself the\n * extension would install into `rebase`, and every unqualified `VECTOR(n)`\n * below would fail to resolve.\n */\nexport const VECTOR_EXTENSION_SCHEMA = \"public\";\n\n/** The extension name a database has to name to let Rebase install pgvector. */\nexport const VECTOR_EXTENSION = \"vector\";\n\n/**\n * How a project says Rebase may install pgvector, quoted into the messages that\n * have to name it. Spelled once so the option and the advice cannot drift.\n */\nexport const VECTOR_EXTENSION_OPT_IN = `database({ extensions: [\"${VECTOR_EXTENSION}\"] })`;\n\n/** Did the project give Rebase leave to install pgvector? */\nexport const vectorExtensionDeclared = (extensions: readonly string[] | undefined): boolean =>\n (extensions ?? []).includes(VECTOR_EXTENSION);\n\n/**\n * Install pgvector — emitted only when the database asked for it.\n *\n * Opt-in because installing an extension is a decision with a deployment behind\n * it: the image has to ship the library, the role has to be allowed to install\n * it, and a managed provider has to have it on an allow-list. None of that is\n * visible from inside the connection, so Rebase does not decide it. See\n * `DatabaseOptions.extensions`.\n *\n * Withholding the statement is not withholding the *column*: the column is\n * still created, and Postgres refuses it with `type \"vector\" does not exist`\n * on a database where pgvector was never installed by hand. That error is the\n * one this design accepts, and `vectorExtensionHint` is what makes it name\n * {@link VECTOR_EXTENSION_OPT_IN} rather than nothing.\n */\nexport const vectorExtensionStatement = (): string =>\n `CREATE EXTENSION IF NOT EXISTS ${VECTOR_EXTENSION} WITH SCHEMA ${VECTOR_EXTENSION_SCHEMA};`;\n\n/**\n * The missing-pgvector explanation, appended to whichever error revealed it.\n *\n * Two readers, needing opposite things, which is why the branch is on the error\n * text rather than on the configuration:\n *\n * - **`type \"vector\" does not exist`** — nobody opted in and the database has\n * no pgvector. The fix is one line of config they cannot guess, so naming\n * the option *is* the hint.\n * - **the install itself failed** — the config is already right, and repeating\n * the option would send them to edit a correct line. What is missing is the\n * library on the server, or the grant.\n *\n * Lives here rather than beside either caller because both need it: the boot\n * ensure raises the first through its action applier, and `rebase db push`\n * raises it out of `applyVectorDdl`. A hint on only one path is how a bare\n * `type \"vector\" does not exist` reaches somebody — which is the thing this\n * exists to prevent.\n */\nexport const vectorExtensionHint = (message: string): string => {\n const installRefused = /extension \"vector\" is not available/i.test(message)\n || /(permission denied to create extension|must be (superuser|owner).{0,40}extension)/i.test(message);\n if (installRefused) {\n return (\n \"\\n pgvector was declared and could not be installed. It is a server extension, so it needs an image \" +\n \"that ships the library (the scaffold's `pgvector/pgvector:pg18` does; a stock `postgres:18` does not) \" +\n \"and a role allowed to run `CREATE EXTENSION vector;`. Managed Postgres usually allows it once the \" +\n \"extension is on the provider's allow-list.\"\n );\n }\n if (!/type \"(vector|halfvec|sparsevec)\" does not exist/i.test(message)) return \"\";\n return (\n \"\\n pgvector is not installed on this database, and Rebase installs it only where a database says it may: \" +\n `add \\`${VECTOR_EXTENSION_OPT_IN}\\` in config/resources.ts, or install it once by hand with ` +\n \"`CREATE EXTENSION vector;`. Either way the server needs an image that ships the library — the scaffold's \" +\n \"`pgvector/pgvector:pg18` does, a stock `postgres:18` does not. Rebase then creates the column and its ANN \" +\n \"index automatically — see the `index` option on the property.\"\n );\n};\n\n/** One `{ type: \"vector\" }` property, as a column. */\nexport interface VectorColumnSpec {\n schema: string;\n table: string;\n column: string;\n dimensions: number;\n /** Rendered after the type, in the generator's order: UNIQUE then NOT NULL. */\n modifiers: string;\n}\n\n/**\n * Every vector column a collection declares.\n *\n * Wider than {@link buildVectorIndexPlan} on purpose: that one answers \"what\n * gets an ANN index\", and skips both a property with `index: false` and one too\n * wide to index. Either still needs its column.\n */\nexport const buildVectorColumnSpecs = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): VectorColumnSpec[] => {\n const table = getTableName(collection);\n const schema = isPostgresCollectionConfig(collection) && collection.schema ? collection.schema : \"public\";\n const specs: VectorColumnSpec[] = [];\n\n for (const [propName, prop] of Object.entries(collection.properties ?? {})) {\n if (!isVectorProperty(prop)) continue;\n // Assembled in the CREATE TABLE generator's order, so the column this\n // file adds and the column `schema.sql` used to declare are the same\n // column. A vector property is never a primary key and carries no\n // SQL-level default, which is what leaves only these two.\n const validation = (prop as { validation?: { required?: boolean; unique?: boolean } }).validation;\n let modifiers = \"\";\n if (validation?.unique) modifiers += \" UNIQUE\";\n if (validation?.required) modifiers += \" NOT NULL\";\n specs.push({\n schema,\n table,\n column: resolveColumn(propName, prop as Property),\n dimensions: prop.dimensions,\n modifiers\n });\n }\n\n return specs;\n};\n\n/** The column type — the one place `VECTOR(n)` is spelled. */\nexport const vectorColumnType = (spec: Pick<VectorColumnSpec, \"dimensions\">): string =>\n `VECTOR(${spec.dimensions})`;\n\n/** The column definition as it appears inside `CREATE TABLE`. */\nexport const vectorColumnDefinition = (spec: VectorColumnSpec): string =>\n `\"${spec.column}\" ${vectorColumnType(spec)}${spec.modifiers}`;\n\n/**\n * Refuse — or perform — a `dimensions` change that `ADD COLUMN IF NOT EXISTS`\n * would otherwise swallow.\n *\n * Without this the file *launders* the change: the ADD is a no-op against a\n * column that exists, so a project that went from 384 to 768 dimensions would\n * push clean, keep a 384-wide column, and fail on the next insert with a\n * message about the row rather than about the config. Atlas used to catch this\n * — it owned the column and planned the `ALTER … TYPE` — and taking the column\n * out of its sight is exactly what makes the guard necessary.\n *\n * The widening is performed when the column holds no values, because that is\n * the case Atlas handled and it is the common one: a developer changing\n * embedding models before there are any embeddings. With values present the\n * conversion is pgvector's to reject — every stored vector is the old width —\n * so this refuses first and names the statement to run afterwards.\n *\n * `atttypmod` on a `vector` column *is* the dimension count: pgvector stores it\n * directly rather than offsetting it the way `varchar` does. `-1` means the\n * column was declared as a bare `vector`, which is drift in the same sense.\n */\nexport const vectorDimensionGuard = (spec: VectorColumnSpec): string => {\n const relation = `\"${spec.schema}\".\"${spec.table}\"`;\n return `DO $rebase_vector$\nDECLARE actual int;\nBEGIN\n SELECT a.atttypmod INTO actual\n FROM pg_attribute a\n JOIN pg_type t ON t.oid = a.atttypid\n WHERE a.attrelid = ${quote(relation)}::regclass\n AND a.attname = ${quote(spec.column)}\n AND NOT a.attisdropped\n AND t.typname = 'vector';\n IF actual IS NOT NULL AND actual <> ${spec.dimensions} THEN\n IF EXISTS (SELECT 1 FROM ${relation} WHERE \"${spec.column}\" IS NOT NULL) THEN\n RAISE EXCEPTION 'Rebase: ${spec.schema}.${spec.table}.\"${spec.column}\" declares ${spec.dimensions} dimensions but the column is vector(%), and it already holds values of the old width. pgvector cannot convert them. Re-embed the rows at ${spec.dimensions} dimensions (or clear the column), then re-apply: ALTER TABLE ${relation} ALTER COLUMN \"${spec.column}\" TYPE ${vectorColumnType(spec)};', actual;\n END IF;\n ALTER TABLE ${relation} ALTER COLUMN \"${spec.column}\" TYPE ${vectorColumnType(spec)};\n END IF;\nEND\n$rebase_vector$;`;\n};\n\n/**\n * The object names a collection's vector properties own, unqualified.\n *\n * What Atlas has to be told to exclude. Only the column and the ANN indexes: a\n * `UNIQUE` or `NOT NULL` on the column is a property *of* the column, and\n * excluding the column takes them with it — measured against Atlas 1.2.3 and\n * 1.3.2, where a target carrying `vector(3) NOT NULL UNIQUE` and a `schema.sql`\n * carrying neither reported \"Schema is synced, no changes to be made\".\n */\nexport const vectorObjectNames = (\n collection: CollectionConfig,\n resolveColumn: (propName: string, prop?: Property | null) => string\n): string[] => [\n ...buildVectorColumnSpecs(collection, resolveColumn).map(spec => spec.column),\n ...vectorIndexNames(buildVectorIndexPlan(collection, resolveColumn))\n];\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  __createRequire(import.meta.url);
3
- import { n as __exportAll } from "./rolldown-runtime-V7rFbMRe.js";
4
- import { A as budgetSendBuffers, M as terminateIfBacklogged, N as assertReadRequestReadable, ct as SqlResultTooLargeError, it as effectiveSqlRole, j as reapSilentSockets, lt as isNestedPath, ot as sqlRoleRanAs, st as SQL_RESULT_BYTE_BUDGET, ut as resolveNestedPath } from "./open-rebase-BKA7Nyoe.js";
5
- import { r as BranchingUnsupportedError } from "./BranchService-iXXZeVYD.js";
3
+ import { i as __exportAll } from "./cli-prompt-DXG0yk-h.js";
4
+ import { A as budgetSendBuffers, M as terminateIfBacklogged, N as assertReadRequestReadable, ct as SqlResultTooLargeError, it as effectiveSqlRole, j as reapSilentSockets, lt as isNestedPath, ot as sqlRoleRanAs, st as SQL_RESULT_BYTE_BUDGET, ut as resolveNestedPath } from "./open-rebase-EmqVmS14.js";
5
+ import { r as BranchingUnsupportedError } from "./BranchService-ClklxyAQ.js";
6
6
  import { ApiError, DATABASE_UNAVAILABLE_MESSAGE, RUNTIME_DEFAULT_MAX_BODY_SIZE, assertFieldOpsValid, assertNestedWriteAllowed, assertNoFieldOpsOnCreate, assertNoUserUpsert, assertUserCreationBodyValid, assertWriteRequestValid, createUserThroughAuthCollection, decideImpersonation, declaredErrorAnswer, extractUserFromToken, getAccessModel, isDatabaseUnreachable, logger, resolveConflictTarget, resolveRequireAuth, safeCompare } from "@rebasepro/server";
7
7
  import { ANONYMOUS_USER_ID, ListLimitError, hasAdminRole, isSQLAdmin, isSchemaAdmin, resolveClientListLimit, scopeGrants, scopesForRoles } from "@rebasepro/types";
8
8
  import { UnknownFilterOperatorError, deserializeFilter, redactSqlLiterals } from "@rebasepro/common";
@@ -142,6 +142,8 @@ function scriptDescription({ rows: _rows, ...description }) {
142
142
  * person's session.
143
143
  */
144
144
  var SERVICE_KEY_UID = "service";
145
+ /** The `id` of the built-in auth adapter (`createBuiltinAuthAdapter` in `@rebasepro/server`). */
146
+ var BUILTIN_AUTH_ADAPTER_ID = "rebase-builtin";
145
147
  /** Maximum messages per client per window */
146
148
  var WS_RATE_LIMIT = 2e3;
147
149
  /** Rate limit window in milliseconds (60 seconds) */
@@ -576,7 +578,18 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig, au
576
578
  };
577
579
  }
578
580
  if (authAdapter) {
579
- const adapterUser = authAdapter.verifyToken ? await authAdapter.verifyToken(token) : await authAdapter.verifyRequest(new Request("http://localhost/_ws_auth", { headers: { Authorization: `Bearer ${token}` } }));
581
+ const builtIn = authAdapter.id === BUILTIN_AUTH_ADAPTER_ID;
582
+ let adapterUser;
583
+ try {
584
+ adapterUser = authAdapter.verifyToken && !builtIn ? await authAdapter.verifyToken(token) : await authAdapter.verifyRequest(new Request("http://localhost/_ws_auth", { headers: { Authorization: `Bearer ${token}` } }));
585
+ } catch (error) {
586
+ const declared = builtIn ? declaredErrorAnswer(error) : void 0;
587
+ if (declared?.status === 401) return {
588
+ refused: declared.message,
589
+ code: declared.code
590
+ };
591
+ throw error;
592
+ }
580
593
  if (!adapterUser) return { refused: "Invalid or expired token" };
581
594
  return {
582
595
  credential: adapterUser.uid === SERVICE_KEY_UID ? "service-key" : "session",
@@ -1629,4 +1642,4 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig, au
1629
1642
  //#endregion
1630
1643
  export { createPostgresWebSocket as a, websocket_exports as c, TOO_MANY_SOCKETS_CLOSE_CODE as i, PUBLIC_TYPES as n, isSocketRealtimeService as o, SESSION_ENDED_CLOSE_CODE as r, socketRealtimeMissing as s, ADMIN_PLANE_TYPES as t };
1631
1644
 
1632
- //# sourceMappingURL=websocket-MC0zTBar.js.map
1645
+ //# sourceMappingURL=websocket-BKZwsjmf.js.map