@prisma-next/target-postgres 0.16.0-dev.25 → 0.16.0-dev.27
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.
- package/dist/{authoring-BCzcFRay.mjs → authoring-DnO1B0N9.mjs} +7 -14
- package/dist/authoring-DnO1B0N9.mjs.map +1 -0
- package/dist/canonicalize-C7zKHw8m.mjs +59 -0
- package/dist/canonicalize-C7zKHw8m.mjs.map +1 -0
- package/dist/{canonicalize-D1F4vUnP.d.mts → canonicalize-CQlxSR4D.d.mts} +3 -18
- package/dist/canonicalize-CQlxSR4D.d.mts.map +1 -0
- package/dist/contract-free.d.mts +1 -1
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +1 -1
- package/dist/{control-policy-B-_34g05.mjs → control-policy-DEwdS3oK.mjs} +23 -24
- package/dist/control-policy-DEwdS3oK.mjs.map +1 -0
- package/dist/control.mjs +10 -7
- package/dist/control.mjs.map +1 -1
- package/dist/{ddl-DYEob9xQ.mjs → ddl-BQC6u-L9.mjs} +27 -3
- package/dist/{ddl-DYEob9xQ.mjs.map → ddl-BQC6u-L9.mjs.map} +1 -1
- package/dist/ddl.d.mts +3 -3
- package/dist/ddl.mjs +2 -2
- package/dist/{descriptor-meta-D_0ZKcj-.mjs → descriptor-meta-DGlJurgA.mjs} +2 -2
- package/dist/{descriptor-meta-D_0ZKcj-.mjs.map → descriptor-meta-DGlJurgA.mjs.map} +1 -1
- package/dist/{diff-database-schema-C9H09OD3.mjs → diff-database-schema-qRPwuYBH.mjs} +22 -12
- package/dist/diff-database-schema-qRPwuYBH.mjs.map +1 -0
- package/dist/diff-database-schema.mjs +1 -1
- package/dist/errors.d.mts +4 -2
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +2 -2
- package/dist/issue-planner.d.mts +2 -2
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +2 -2
- package/dist/migration.mjs +2 -2
- package/dist/{nodes-DJC5B8Id.mjs → nodes-04EILM-z.mjs} +65 -2
- package/dist/nodes-04EILM-z.mjs.map +1 -0
- package/dist/{nodes-CQzM2hR0.d.mts → nodes-DjCsN-uv.d.mts} +69 -4
- package/dist/nodes-DjCsN-uv.d.mts.map +1 -0
- package/dist/{op-factory-call-DT7kdjVP.d.mts → op-factory-call-0TB5XNij.d.mts} +46 -8
- package/dist/op-factory-call-0TB5XNij.d.mts.map +1 -0
- package/dist/{op-factory-call-BVYLIojV.mjs → op-factory-call-CIaPDDUc.mjs} +104 -27
- package/dist/op-factory-call-CIaPDDUc.mjs.map +1 -0
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-4sj5cJCY.mjs → planner-BhnkIJX-.mjs} +117 -9
- package/dist/planner-BhnkIJX-.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-CcQPDWmX.mjs → planner-produced-postgres-migration-BE3EJIRK.mjs} +2 -2
- package/dist/{planner-produced-postgres-migration-CcQPDWmX.mjs.map → planner-produced-postgres-migration-BE3EJIRK.mjs.map} +1 -1
- package/dist/{planner-produced-postgres-migration-8QP8eMph.d.mts → planner-produced-postgres-migration-CRAHl6ak.d.mts} +2 -2
- package/dist/planner-produced-postgres-migration-CRAHl6ak.d.mts.map +1 -0
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-schema-lookup-CiVaAQP-.mjs → planner-schema-lookup-D3Y_OL-C.mjs} +3 -3
- package/dist/planner-schema-lookup-D3Y_OL-C.mjs.map +1 -0
- package/dist/planner-schema-lookup.mjs +1 -1
- package/dist/planner.d.mts +21 -1
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +2 -2
- package/dist/{postgres-contract-view-B8yXVWYe.mjs → postgres-contract-view-BeIEyZfD.mjs} +2 -2
- package/dist/{postgres-contract-view-B8yXVWYe.mjs.map → postgres-contract-view-BeIEyZfD.mjs.map} +1 -1
- package/dist/{postgres-migration-GIOABsAa.mjs → postgres-migration--BzvpA92.mjs} +7 -4
- package/dist/postgres-migration--BzvpA92.mjs.map +1 -0
- package/dist/{postgres-migration-DLIvzHjX.d.mts → postgres-migration-BXelnqHO.d.mts} +15 -10
- package/dist/postgres-migration-BXelnqHO.d.mts.map +1 -0
- package/dist/rls-canonicalize.d.mts +2 -26
- package/dist/rls-canonicalize.mjs +2 -2
- package/dist/runtime.mjs +1 -1
- package/package.json +20 -20
- package/src/contract-free/ddl.ts +47 -0
- package/src/core/authoring.ts +10 -22
- package/src/core/ddl/nodes.ts +104 -0
- package/src/core/migrations/contract-to-postgres-database-schema-node.ts +24 -13
- package/src/core/migrations/issue-planner.ts +40 -13
- package/src/core/migrations/op-factory-call.ts +100 -9
- package/src/core/migrations/operations/indexes.ts +80 -35
- package/src/core/migrations/planner-schema-lookup.ts +2 -2
- package/src/core/migrations/planner.ts +155 -5
- package/src/core/migrations/postgres-migration.ts +26 -8
- package/src/core/psl-infer/infer-psl-contract.ts +8 -1
- package/src/core/rls/canonicalize.ts +4 -21
- package/src/exports/ddl.ts +4 -0
- package/src/exports/errors.ts +1 -1
- package/src/exports/op-factory-call.ts +1 -0
- package/src/exports/rls-canonicalize.ts +0 -6
- package/dist/authoring-BCzcFRay.mjs.map +0 -1
- package/dist/canonicalize-D1F4vUnP.d.mts.map +0 -1
- package/dist/control-policy-B-_34g05.mjs.map +0 -1
- package/dist/diff-database-schema-C9H09OD3.mjs.map +0 -1
- package/dist/nodes-CQzM2hR0.d.mts.map +0 -1
- package/dist/nodes-DJC5B8Id.mjs.map +0 -1
- package/dist/op-factory-call-BVYLIojV.mjs.map +0 -1
- package/dist/op-factory-call-DT7kdjVP.d.mts.map +0 -1
- package/dist/planner-4sj5cJCY.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-8QP8eMph.d.mts.map +0 -1
- package/dist/planner-schema-lookup-CiVaAQP-.mjs.map +0 -1
- package/dist/postgres-migration-DLIvzHjX.d.mts.map +0 -1
- package/dist/postgres-migration-GIOABsAa.mjs.map +0 -1
- package/dist/rls-canonicalize.d.mts.map +0 -1
- package/dist/wire-name-DbQ9-2RC.mjs +0 -104
- package/dist/wire-name-DbQ9-2RC.mjs.map +0 -1
- package/src/core/rls/wire-name.ts +0 -33
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-migration-GIOABsAa.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/migrations/postgres-migration.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { Migration as SqlMigration } from '@prisma-next/family-sql/migration';\nimport type { ControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationContractViews } from '@prisma-next/migration-tools/migration';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { errorPostgresMigrationStackMissing } from '../errors';\nimport { PostgresContractView } from '../postgres-contract-view';\nimport { PostgresRlsPolicy, type PostgresRlsPolicyInput } from '../postgres-rls-policy';\nimport {\n AddCheckConstraintCall,\n AddColumnCall,\n AddForeignKeyCall,\n AddNativeEnumValueCall,\n AddPrimaryKeyCall,\n AddUniqueCall,\n AlterColumnTypeCall,\n type AlterColumnTypeOptions,\n CreateIndexCall,\n CreateNativeEnumTypeCall,\n CreatePostgresRlsPolicyCall,\n CreateSchemaCall,\n CreateTableCall,\n DisableRowLevelSecurityCall,\n DropCheckConstraintCall,\n DropColumnCall,\n DropConstraintCall,\n DropDefaultCall,\n DropIndexCall,\n DropNativeEnumTypeCall,\n DropNotNullCall,\n DropPostgresRlsPolicyCall,\n DropTableCall,\n EnableRowLevelSecurityCall,\n RenamePostgresRlsPolicyCall,\n SetDefaultCall,\n SetNotNullCall,\n} from './op-factory-call';\nimport { type DataTransformOptions, dataTransform } from './operations/data-transform';\nimport { installExtension } from './operations/dependencies';\nimport type { CreateIndexExtras } from './operations/indexes';\nimport type { ForeignKeySpec } from './operations/shared';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\n\n/**\n * Target-owned base class for Postgres migrations.\n *\n * Fixes the `SqlMigration` generic to `PostgresPlanTargetDetails` and the\n * abstract `targetId` to the Postgres target-id string literal, so both\n * user-authored migrations and renderer-generated scaffolds (the output of\n * `renderCallsToTypeScript`) can extend `PostgresMigration` directly without\n * redeclaring target-local identity.\n *\n * Mirrors `MongoMigration` in `@prisma-next/family-mongo`: the renderer\n * emits `extends Migration` against a facade re-export of this class\n * from `@prisma-next/postgres/migration`, keeping the authoring surface\n * target-scoped rather than family-scoped.\n *\n * The constructor materializes a single Postgres `SqlControlAdapter` from\n * `stack.adapter.create(stack)` and stores it; the protected `dataTransform`\n * instance method forwards to the free `dataTransform` factory with that\n * stored adapter, so user migrations can write `this.dataTransform(...)`\n * without threading the adapter through every call.\n *\n * Every method requires an explicit `schema`. Postgres migrations name their\n * schema deliberately — there is no default and no `search_path`-relative\n * option. A migration that left the schema unspecified would resolve against\n * whatever `search_path` the connection happened to carry, and that ambiguity\n * is an antipattern in a migration. (The unbound/unspecified namespace concept\n * remains for SQLite, which has no schemas, and for Mongo's connection `db`.)\n */\nexport abstract class PostgresMigration<\n Start extends Contract<SqlStorage> = Contract<SqlStorage>,\n End extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends SqlMigration<PostgresPlanTargetDetails, 'postgres', Start, End> {\n readonly targetId = 'postgres' as const;\n\n /**\n * Materialized Postgres control adapter, created once per migration\n * instance from the injected stack. `undefined` only when the migration\n * was instantiated without a stack (test fixtures); `controlAdapterFor`\n * throws a MIGRATION.POSTGRES_CONTROL_STACK_MISSING in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'postgres'> | undefined;\n\n #endView = new MigrationContractViews<PostgresContractView<End>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<End>(json),\n );\n #startView = new MigrationContractViews<PostgresContractView<Start>>(\n this,\n 'PostgresMigration',\n (json) => PostgresContractView.fromJson<Start>(json),\n );\n\n constructor(stack?: ControlStack<'sql', 'postgres'>) {\n super(stack);\n // The descriptor `create()` is typed as the wider `ControlAdapterInstance`;\n // the Postgres descriptor concretely returns a `SqlControlAdapter<'postgres'>`,\n // so the cast holds for any Postgres-target stack assembled at runtime.\n this.controlAdapter = stack?.adapter\n ? (stack.adapter.create(stack) as SqlControlAdapter<'postgres'>)\n : undefined;\n }\n\n /**\n * Returns the materialized control adapter, or throws a MIGRATION.POSTGRES_CONTROL_STACK_MISSING naming\n * `operation` when the migration was constructed without a `ControlStack`.\n * Single home for the null-check that every DDL/DML method shares.\n */\n private controlAdapterFor(operation: string): SqlControlAdapter<'postgres'> {\n if (!this.controlAdapter) {\n throw errorPostgresMigrationStackMissing(operation);\n }\n return this.controlAdapter;\n }\n\n /**\n * The typed, schema-qualified Postgres view over this migration's end-state\n * contract — `this.endContract.namespace.<schema>.table.<name>`, etc. Throws\n * if no `endContractJson` was provided.\n */\n get endContract(): PostgresContractView<End> {\n return this.#endView.endContract;\n }\n\n /**\n * The typed Postgres view over this migration's start-state contract, or\n * `null` for a baseline migration (no `startContractJson`).\n */\n get startContract(): PostgresContractView<Start> | null {\n return this.#startView.startContract;\n }\n\n /**\n * Instance-method wrapper around the free `dataTransform` factory that\n * supplies the stored control adapter. Authors call this from inside\n * `get operations()`; the adapter argument is hidden from the call site.\n */\n protected dataTransform<TContract extends Contract<SqlStorage>>(\n contract: TContract,\n name: string,\n options: DataTransformOptions,\n ): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return dataTransform(contract, name, options, this.controlAdapterFor('dataTransform'));\n }\n\n /**\n * Emit a `CREATE TABLE` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createTable(options: {\n readonly schema: string;\n readonly table: string;\n readonly ifNotExists?: boolean;\n readonly columns: readonly DdlColumn[];\n readonly constraints?: readonly DdlTableConstraint[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateTableCall(\n options.schema,\n options.table,\n options.columns,\n options.constraints,\n ).toOp(this.controlAdapterFor('createTable'));\n }\n\n /**\n * Emit a `CREATE SCHEMA` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\n */\n protected createSchema(options: {\n readonly schema: string;\n readonly ifNotExists?: boolean;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateSchemaCall(options.schema).toOp(this.controlAdapterFor('createSchema'));\n }\n\n /**\n * Emit a `CREATE TYPE ... AS ENUM (...)` migration operation for a managed\n * native enum. Builds a typed DDL node and lowers it through the stored\n * control adapter (members render in declaration order). Throws if no adapter\n * is present.\n */\n protected createNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly members: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateNativeEnumTypeCall(options.schema, options.typeName, options.members).toOp(\n this.controlAdapterFor('createNativeEnumType'),\n );\n }\n\n /**\n * Emit a `DROP TYPE` migration operation for a managed native enum, lowered\n * through the stored control adapter. Throws if no adapter is present.\n */\n protected dropNativeEnumType(options: {\n readonly schema: string;\n readonly typeName: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNativeEnumTypeCall(options.schema, options.typeName).toOp(\n this.controlAdapterFor('dropNativeEnumType'),\n );\n }\n\n /**\n * Emit an `ALTER TYPE ... ADD VALUE` migration operation appending one\n * member to a managed native enum, lowered through the stored control\n * adapter. Throws if no adapter is present. Every appended value is its\n * own operation — call this once per value to append more than one.\n */\n protected addNativeEnumValue(options: {\n readonly schema: string;\n readonly typeName: string;\n readonly value: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddNativeEnumValueCall(options.schema, options.typeName, options.value).toOp(\n this.controlAdapterFor('addNativeEnumValue'),\n );\n }\n\n protected addColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: DdlColumn;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('addColumn'),\n );\n }\n\n protected addPrimaryKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddPrimaryKeyCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addPrimaryKey'));\n }\n\n protected addUnique(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly columns: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddUniqueCall(\n options.schema,\n options.table,\n options.constraint,\n options.columns,\n ).toOp(this.controlAdapterFor('addUnique'));\n }\n\n protected addForeignKey(options: {\n readonly schema: string;\n readonly table: string;\n readonly foreignKey: ForeignKeySpec;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddForeignKeyCall(options.schema, options.table, options.foreignKey).toOp(\n this.controlAdapterFor('addForeignKey'),\n );\n }\n\n protected addCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly column: string;\n readonly values: readonly string[];\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AddCheckConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.column,\n options.values,\n ).toOp(this.controlAdapterFor('addCheckConstraint'));\n }\n\n protected dropCheckConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropCheckConstraintCall(options.schema, options.table, options.constraint).toOp(\n this.controlAdapterFor('dropCheckConstraint'),\n );\n }\n\n protected dropConstraint(options: {\n readonly schema: string;\n readonly table: string;\n readonly constraint: string;\n readonly kind?: 'foreignKey' | 'unique' | 'primaryKey';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropConstraintCall(\n options.schema,\n options.table,\n options.constraint,\n options.kind ?? 'unique',\n ).toOp(this.controlAdapterFor('dropConstraint'));\n }\n\n protected dropTable(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropTableCall(options.schema, options.table).toOp(\n this.controlAdapterFor('dropTable'),\n );\n }\n\n protected dropColumn(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropColumnCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropColumn'),\n );\n }\n\n protected alterColumnType(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly options: AlterColumnTypeOptions;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new AlterColumnTypeCall(\n options.schema,\n options.table,\n options.column,\n options.options,\n ).toOp(this.controlAdapterFor('alterColumnType'));\n }\n\n protected setNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('setNotNull'),\n );\n }\n\n protected dropNotNull(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropNotNullCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropNotNull'),\n );\n }\n\n protected setDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly defaultSql: string;\n readonly operationClass?: 'additive' | 'widening';\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new SetDefaultCall(\n options.schema,\n options.table,\n options.column,\n options.defaultSql,\n options.operationClass,\n ).toOp(this.controlAdapterFor('setDefault'));\n }\n\n protected dropDefault(options: {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropDefaultCall(options.schema, options.table, options.column).toOp(\n this.controlAdapterFor('dropDefault'),\n );\n }\n\n protected createIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n readonly columns: readonly string[];\n readonly extras?: CreateIndexExtras;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreateIndexCall(\n options.schema,\n options.table,\n options.index,\n options.columns,\n options.extras,\n ).toOp(this.controlAdapterFor('createIndex'));\n }\n\n protected dropIndex(options: {\n readonly schema: string;\n readonly table: string;\n readonly index: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropIndexCall(options.schema, options.table, options.index).toOp(\n this.controlAdapterFor('dropIndex'),\n );\n }\n\n protected installExtension(options: {\n readonly extensionName: string;\n readonly invariantId: string;\n readonly id: string;\n readonly label?: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return installExtension(options, this.controlAdapterFor('installExtension'));\n }\n\n protected enableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new EnableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('enableRowLevelSecurity'),\n );\n }\n\n protected disableRowLevelSecurity(options: {\n readonly schema: string;\n readonly table: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DisableRowLevelSecurityCall(options.schema, options.table).toOp(\n this.controlAdapterFor('disableRowLevelSecurity'),\n );\n }\n\n protected createRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: PostgresRlsPolicyInput;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new CreatePostgresRlsPolicyCall(\n options.schema,\n options.table,\n new PostgresRlsPolicy(options.policy),\n ).toOp(this.controlAdapterFor('createRlsPolicy'));\n }\n\n protected dropRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly policy: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new DropPostgresRlsPolicyCall(options.schema, options.table, options.policy).toOp(\n this.controlAdapterFor('dropRlsPolicy'),\n );\n }\n\n protected renameRlsPolicy(options: {\n readonly schema: string;\n readonly table: string;\n readonly from: string;\n readonly to: string;\n }): Promise<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> {\n return new RenamePostgresRlsPolicyCall(\n options.schema,\n options.table,\n options.from,\n options.to,\n ).toOp(this.controlAdapterFor('renameRlsPolicy'));\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rls-canonicalize.d.mts","names":[],"sources":["../src/core/rls/wire-name.ts"],"mappings":";;UAAiB;;WAEN;;WAEA;;;;;;;;iBAWK,wBAAwB,gBAAgB;;;;;;;;iBAWxC,uBAAuB,eAAe"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
//#region src/core/rls/canonicalize.ts
|
|
3
|
-
/**
|
|
4
|
-
* Which predicate each RLS operation admits, mirroring Postgres: SELECT and
|
|
5
|
-
* DELETE decide row visibility/eligibility with `USING` only; INSERT
|
|
6
|
-
* validates the new row with `WITH CHECK` only; UPDATE and ALL take either
|
|
7
|
-
* or both. Single-homed here so the PSL lowering and the TS handle
|
|
8
|
-
* constructors enforce the same matrix.
|
|
9
|
-
*/
|
|
10
|
-
const POLICY_OPERATION_PREDICATES = {
|
|
11
|
-
select: {
|
|
12
|
-
using: true,
|
|
13
|
-
withCheck: false
|
|
14
|
-
},
|
|
15
|
-
insert: {
|
|
16
|
-
using: false,
|
|
17
|
-
withCheck: true
|
|
18
|
-
},
|
|
19
|
-
update: {
|
|
20
|
-
using: true,
|
|
21
|
-
withCheck: true
|
|
22
|
-
},
|
|
23
|
-
delete: {
|
|
24
|
-
using: true,
|
|
25
|
-
withCheck: false
|
|
26
|
-
},
|
|
27
|
-
all: {
|
|
28
|
-
using: true,
|
|
29
|
-
withCheck: true
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Stabilizes an authored predicate for hashing: trim, and collapse runs of
|
|
34
|
-
* internal whitespace to a single space.
|
|
35
|
-
*
|
|
36
|
-
* This is deliberately minimal. The content hash is the equivalence relation
|
|
37
|
-
* for a policy, and the wire name (prefix + hash) is the only thing ever
|
|
38
|
-
* compared — we never recompute the hash from an introspected policy body, so
|
|
39
|
-
* there is no need to match Postgres's reprinted form. Minimal normalization
|
|
40
|
-
* also protects the no-collision property: aggressive rewriting (lowercasing,
|
|
41
|
-
* paren-stripping, cast-alias folding) risks collapsing two distinct predicates
|
|
42
|
-
* onto one hash. Out-of-band alteration of a hashed policy is unsupported.
|
|
43
|
-
*
|
|
44
|
-
* The normalizer is a stability commitment: any change re-suffixes all wire names.
|
|
45
|
-
*/
|
|
46
|
-
function normalizePredicate(sql) {
|
|
47
|
-
return sql.replace(/\s+/g, " ").trim();
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Returns the first 8 lowercase hex characters of the SHA-256 digest over the
|
|
51
|
-
* canonical content tuple for an RLS policy:
|
|
52
|
-
*
|
|
53
|
-
* [normalize(using), normalize(withCheck), sortedRoles, operation, permissive]
|
|
54
|
-
*
|
|
55
|
-
* Schema and table are excluded (they are orthogonal to policy equivalence).
|
|
56
|
-
* Uses `JSON.stringify` for a deterministic encoding.
|
|
57
|
-
*/
|
|
58
|
-
function computeContentHash(parts) {
|
|
59
|
-
const using = normalizePredicate(parts.using ?? "");
|
|
60
|
-
const withCheck = normalizePredicate(parts.withCheck ?? "");
|
|
61
|
-
const roles = [...new Set(parts.roles)].sort();
|
|
62
|
-
const permissive = parts.permissive ? "permissive" : "restrictive";
|
|
63
|
-
const tuple = JSON.stringify([
|
|
64
|
-
using,
|
|
65
|
-
withCheck,
|
|
66
|
-
roles,
|
|
67
|
-
parts.operation,
|
|
68
|
-
permissive
|
|
69
|
-
]);
|
|
70
|
-
return createHash("sha256").update(tuple).digest("hex").slice(0, 8);
|
|
71
|
-
}
|
|
72
|
-
//#endregion
|
|
73
|
-
//#region src/core/rls/wire-name.ts
|
|
74
|
-
const WIRE_NAME_PATTERN = /^(.+)_([0-9a-f]{8})$/;
|
|
75
|
-
/**
|
|
76
|
-
* Assembles an RLS policy wire name from its user-supplied prefix and its
|
|
77
|
-
* 8-hex content-hash suffix. This module owns the `<prefix>_<hash>` format
|
|
78
|
-
* on both sides — construction here and parsing in
|
|
79
|
-
* {@link parseRlsPolicyWireName} — so the two never drift.
|
|
80
|
-
*/
|
|
81
|
-
function formatRlsPolicyWireName(prefix, hash) {
|
|
82
|
-
return `${prefix}_${hash}`;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Splits an RLS policy wire name (`<prefix>_<8hex>`) into its prefix and
|
|
86
|
-
* content-hash suffix. Returns `undefined` when the name does not follow the
|
|
87
|
-
* wire-name shape (e.g. a policy created outside the toolchain) — callers
|
|
88
|
-
* treat such names as all-prefix. Consumed by introspection (prefix
|
|
89
|
-
* extraction) and by rename pairing (same hash, different prefix).
|
|
90
|
-
*/
|
|
91
|
-
function parseRlsPolicyWireName(name) {
|
|
92
|
-
const match = WIRE_NAME_PATTERN.exec(name);
|
|
93
|
-
const prefix = match?.[1];
|
|
94
|
-
const hash = match?.[2];
|
|
95
|
-
if (prefix === void 0 || hash === void 0) return void 0;
|
|
96
|
-
return {
|
|
97
|
-
prefix,
|
|
98
|
-
hash
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
//#endregion
|
|
102
|
-
export { normalizePredicate as a, computeContentHash as i, parseRlsPolicyWireName as n, POLICY_OPERATION_PREDICATES as r, formatRlsPolicyWireName as t };
|
|
103
|
-
|
|
104
|
-
//# sourceMappingURL=wire-name-DbQ9-2RC.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wire-name-DbQ9-2RC.mjs","names":[],"sources":["../src/core/rls/canonicalize.ts","../src/core/rls/wire-name.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nexport type RlsPolicyOperation = 'select' | 'insert' | 'update' | 'delete' | 'all';\n\n/**\n * Which predicate each RLS operation admits, mirroring Postgres: SELECT and\n * DELETE decide row visibility/eligibility with `USING` only; INSERT\n * validates the new row with `WITH CHECK` only; UPDATE and ALL take either\n * or both. Single-homed here so the PSL lowering and the TS handle\n * constructors enforce the same matrix.\n */\nexport const POLICY_OPERATION_PREDICATES: Readonly<\n Record<RlsPolicyOperation, { readonly using: boolean; readonly withCheck: boolean }>\n> = {\n select: { using: true, withCheck: false },\n insert: { using: false, withCheck: true },\n update: { using: true, withCheck: true },\n delete: { using: true, withCheck: false },\n all: { using: true, withCheck: true },\n};\n\nexport interface ContentHashParts {\n readonly using?: string;\n readonly withCheck?: string;\n readonly roles: readonly string[];\n readonly operation: RlsPolicyOperation;\n readonly permissive: boolean;\n}\n\n/**\n * Stabilizes an authored predicate for hashing: trim, and collapse runs of\n * internal whitespace to a single space.\n *\n * This is deliberately minimal. The content hash is the equivalence relation\n * for a policy, and the wire name (prefix + hash) is the only thing ever\n * compared — we never recompute the hash from an introspected policy body, so\n * there is no need to match Postgres's reprinted form. Minimal normalization\n * also protects the no-collision property: aggressive rewriting (lowercasing,\n * paren-stripping, cast-alias folding) risks collapsing two distinct predicates\n * onto one hash. Out-of-band alteration of a hashed policy is unsupported.\n *\n * The normalizer is a stability commitment: any change re-suffixes all wire names.\n */\nexport function normalizePredicate(sql: string): string {\n return sql.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Returns the first 8 lowercase hex characters of the SHA-256 digest over the\n * canonical content tuple for an RLS policy:\n *\n * [normalize(using), normalize(withCheck), sortedRoles, operation, permissive]\n *\n * Schema and table are excluded (they are orthogonal to policy equivalence).\n * Uses `JSON.stringify` for a deterministic encoding.\n */\nexport function computeContentHash(parts: ContentHashParts): string {\n const using = normalizePredicate(parts.using ?? '');\n const withCheck = normalizePredicate(parts.withCheck ?? '');\n const roles = [...new Set(parts.roles)].sort();\n const permissive = parts.permissive ? 'permissive' : 'restrictive';\n\n const tuple = JSON.stringify([using, withCheck, roles, parts.operation, permissive]);\n return createHash('sha256').update(tuple).digest('hex').slice(0, 8);\n}\n","export interface RlsPolicyWireName {\n /** The user-supplied part before the `_<8hex>` suffix. */\n readonly prefix: string;\n /** The 8-lowercase-hex content-hash suffix. */\n readonly hash: string;\n}\n\nconst WIRE_NAME_PATTERN = /^(.+)_([0-9a-f]{8})$/;\n\n/**\n * Assembles an RLS policy wire name from its user-supplied prefix and its\n * 8-hex content-hash suffix. This module owns the `<prefix>_<hash>` format\n * on both sides — construction here and parsing in\n * {@link parseRlsPolicyWireName} — so the two never drift.\n */\nexport function formatRlsPolicyWireName(prefix: string, hash: string): string {\n return `${prefix}_${hash}`;\n}\n\n/**\n * Splits an RLS policy wire name (`<prefix>_<8hex>`) into its prefix and\n * content-hash suffix. Returns `undefined` when the name does not follow the\n * wire-name shape (e.g. a policy created outside the toolchain) — callers\n * treat such names as all-prefix. Consumed by introspection (prefix\n * extraction) and by rename pairing (same hash, different prefix).\n */\nexport function parseRlsPolicyWireName(name: string): RlsPolicyWireName | undefined {\n const match = WIRE_NAME_PATTERN.exec(name);\n const prefix = match?.[1];\n const hash = match?.[2];\n if (prefix === undefined || hash === undefined) return undefined;\n return { prefix, hash };\n}\n"],"mappings":";;;;;;;;;AAWA,MAAa,8BAET;CACF,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAM;CACxC,QAAQ;EAAE,OAAO;EAAO,WAAW;CAAK;CACxC,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAK;CACvC,QAAQ;EAAE,OAAO;EAAM,WAAW;CAAM;CACxC,KAAK;EAAE,OAAO;EAAM,WAAW;CAAK;AACtC;;;;;;;;;;;;;;;AAwBA,SAAgB,mBAAmB,KAAqB;CACtD,OAAO,IAAI,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;AACvC;;;;;;;;;;AAWA,SAAgB,mBAAmB,OAAiC;CAClE,MAAM,QAAQ,mBAAmB,MAAM,SAAS,EAAE;CAClD,MAAM,YAAY,mBAAmB,MAAM,aAAa,EAAE;CAC1D,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,KAAK;CAC7C,MAAM,aAAa,MAAM,aAAa,eAAe;CAErD,MAAM,QAAQ,KAAK,UAAU;EAAC;EAAO;EAAW;EAAO,MAAM;EAAW;CAAU,CAAC;CACnF,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;AACpE;;;ACzDA,MAAM,oBAAoB;;;;;;;AAQ1B,SAAgB,wBAAwB,QAAgB,MAAsB;CAC5E,OAAO,GAAG,OAAO,GAAG;AACtB;;;;;;;;AASA,SAAgB,uBAAuB,MAA6C;CAClF,MAAM,QAAQ,kBAAkB,KAAK,IAAI;CACzC,MAAM,SAAS,QAAQ;CACvB,MAAM,OAAO,QAAQ;CACrB,IAAI,WAAW,KAAA,KAAa,SAAS,KAAA,GAAW,OAAO,KAAA;CACvD,OAAO;EAAE;EAAQ;CAAK;AACxB"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export interface RlsPolicyWireName {
|
|
2
|
-
/** The user-supplied part before the `_<8hex>` suffix. */
|
|
3
|
-
readonly prefix: string;
|
|
4
|
-
/** The 8-lowercase-hex content-hash suffix. */
|
|
5
|
-
readonly hash: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const WIRE_NAME_PATTERN = /^(.+)_([0-9a-f]{8})$/;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Assembles an RLS policy wire name from its user-supplied prefix and its
|
|
12
|
-
* 8-hex content-hash suffix. This module owns the `<prefix>_<hash>` format
|
|
13
|
-
* on both sides — construction here and parsing in
|
|
14
|
-
* {@link parseRlsPolicyWireName} — so the two never drift.
|
|
15
|
-
*/
|
|
16
|
-
export function formatRlsPolicyWireName(prefix: string, hash: string): string {
|
|
17
|
-
return `${prefix}_${hash}`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Splits an RLS policy wire name (`<prefix>_<8hex>`) into its prefix and
|
|
22
|
-
* content-hash suffix. Returns `undefined` when the name does not follow the
|
|
23
|
-
* wire-name shape (e.g. a policy created outside the toolchain) — callers
|
|
24
|
-
* treat such names as all-prefix. Consumed by introspection (prefix
|
|
25
|
-
* extraction) and by rename pairing (same hash, different prefix).
|
|
26
|
-
*/
|
|
27
|
-
export function parseRlsPolicyWireName(name: string): RlsPolicyWireName | undefined {
|
|
28
|
-
const match = WIRE_NAME_PATTERN.exec(name);
|
|
29
|
-
const prefix = match?.[1];
|
|
30
|
-
const hash = match?.[2];
|
|
31
|
-
if (prefix === undefined || hash === undefined) return undefined;
|
|
32
|
-
return { prefix, hash };
|
|
33
|
-
}
|