1818 * - `consolidated` — additionally inlines FKs proven safe by the graph.
1919 */
2020import { pathFor } from '@pgpmjs/naming-spec' ;
21+ import { revertFor , verifyFor } from '@pgsql/scripts' ;
2122import type { Granularity , StatementFacts } from '@pgsql/transform' ;
2223import {
2324 buildStatementGraph ,
@@ -38,6 +39,22 @@ export interface GranularityChange {
3839 deploy : string ;
3940}
4041
42+ /** A restructured change: deploy plus generated revert/verify scripts. */
43+ export interface RestructuredChange extends GranularityChange {
44+ /**
45+ * Generated revert SQL (headerless): mechanical inverses of the change's
46+ * statements in reverse topological order within the group, via
47+ * `revertFor`. Non-invertible statements leave a `-- revert not
48+ * derivable` comment and a warning.
49+ */
50+ revert : string ;
51+ /**
52+ * Generated verify SQL (headerless): one raise-on-failure existence check
53+ * per created object, via `verifyFor`.
54+ */
55+ verify : string ;
56+ }
57+
4158export interface RestructureModuleOptions {
4259 granularity : Granularity ;
4360 /**
@@ -50,7 +67,7 @@ export interface RestructureModuleOptions {
5067
5168export interface RestructureModuleResult {
5269 /** Restructured changes in deploy order, dependencies recomputed. */
53- changes : GranularityChange [ ] ;
70+ changes : RestructuredChange [ ] ;
5471 /** Non-fatal notes (folds rejected to preserve ordering, etc.). */
5572 warnings : string [ ] ;
5673}
@@ -145,14 +162,17 @@ export function restructureChanges(
145162 }
146163 } ) ;
147164
148- // Slice statement text per group, in the emitted (topological) order.
165+ // Slice statement text per group, in the emitted (topological) order,
166+ // and collect each group's facts for revert/verify generation.
149167 const groupSql : string [ ] [ ] = groupNames . map ( ( ) : string [ ] => [ ] ) ;
168+ const groupStatements : StatementFacts [ ] [ ] = groupNames . map ( ( ) : StatementFacts [ ] => [ ] ) ;
150169
151170 facts . forEach ( ( f , i ) => {
152171 const text = sql . slice ( f . span . start , f . span . start + f . span . len ) . trim ( ) ;
153172 const g = groupOf [ i ] ;
154173 if ( g !== - 1 && text ) {
155174 groupSql [ g ] . push ( text . endsWith ( ';' ) ? text : `${ text } ;` ) ;
175+ groupStatements [ g ] . push ( f ) ;
156176 }
157177 } ) ;
158178
@@ -185,13 +205,25 @@ export function restructureChanges(
185205 return firstA - firstB ;
186206 } ) ;
187207
188- const result : GranularityChange [ ] = order
208+ const result : RestructuredChange [ ] = order
189209 . filter ( g => groupSql [ g ] . length > 0 )
190- . map ( g => ( {
191- name : groupNames [ g ] ,
192- dependencies : [ ...groupDeps [ g ] ] . map ( d => groupNames [ d ] ) . sort ( ) ,
193- deploy : groupSql [ g ] . join ( '\n\n' )
194- } ) ) ;
210+ . map ( g => {
211+ const revert = revertFor ( groupStatements [ g ] ) ;
212+ const verify = verifyFor ( groupStatements [ g ] ) ;
213+ for ( const warning of revert . warnings ) {
214+ warnings . push ( `${ groupNames [ g ] } : ${ warning } ` ) ;
215+ }
216+ for ( const warning of verify . warnings ) {
217+ warnings . push ( `${ groupNames [ g ] } : ${ warning } ` ) ;
218+ }
219+ return {
220+ name : groupNames [ g ] ,
221+ dependencies : [ ...groupDeps [ g ] ] . map ( d => groupNames [ d ] ) . sort ( ) ,
222+ deploy : groupSql [ g ] . join ( '\n\n' ) ,
223+ revert : revert . sql ,
224+ verify : verify . sql
225+ } ;
226+ } ) ;
195227
196228 return { changes : result , warnings } ;
197229}
0 commit comments