@@ -196,6 +196,51 @@ describe("flattened storage: a derived value-object member keeps its column", ()
196196 } ) ;
197197} ) ;
198198
199+ describe ( "flattened storage: a derived flattened parent has no member keys or columns" , ( ) => {
200+ const DERIVED_PARENT = JSON . stringify ( {
201+ "metadata.root" : { package : "acme" , children : [
202+ { "object.value" : { name : "Address" , children : [
203+ { "field.string" : { name : "street" } } ,
204+ { "field.string" : { name : "city" , "@filterable" : true } } ,
205+ ] } } ,
206+ { "object.entity" : { name : "Owner" , children : [
207+ { "source.rdb" : { "@table" : "owners" } } ,
208+ { "field.long" : { name : "id" } } ,
209+ { "field.object" : { name : "home" , "@objectRef" : "Address" , "@storage" : "flattened" } } ,
210+ { "identity.primary" : { name : "pk" , "@fields" : "id" , "@generation" : "increment" } } ,
211+ ] } } ,
212+ { "object.entity" : { name : "Parcel" , children : [
213+ { "source.rdb" : { "@table" : "parcels" , "@role" : "primary" } } ,
214+ { "source.rdb" : { "@kind" : "view" , "@view" : "v_parcels" , "@role" : "replica" } } ,
215+ { "field.long" : { name : "id" } } ,
216+ { "field.string" : { name : "ref" } } ,
217+ { "field.long" : { name : "ownerId" } } ,
218+ { "field.object" : { name : "shipTo" , "@objectRef" : "Address" , "@storage" : "flattened" , children : [
219+ { "origin.passthrough" : { "@from" : "Owner.home" , "@via" : "Parcel.owner" } } ,
220+ ] } } ,
221+ { "identity.primary" : { name : "pk" , "@fields" : "id" , "@generation" : "increment" } } ,
222+ { "identity.reference" : { name : "ownerRef" , "@fields" : "ownerId" , "@references" : "Owner" } } ,
223+ { "relationship.association" : { name : "owner" , "@cardinality" : "one" , "@objectRef" : "Owner" } } ,
224+ ] } } ,
225+ ] } ,
226+ } ) ;
227+
228+ test ( "no flat keys on the surface, in the schemas or allowlists, and no Drizzle member columns" , async ( ) => {
229+ const { root, errors } = await new MetaDataLoader ( { strict : true } ) . load ( [ new InMemoryStringSource ( DERIVED_PARENT , { id : "dp.json" } ) ] ) ;
230+ expect ( errors ) . toEqual ( [ ] ) ;
231+ const parcel = root . findObject ( "Parcel" ) ! ;
232+ expect ( flatSurfaceFields ( parcel ) . map ( ( f ) => f . name ) ) . toEqual ( [ "id" , "ref" , "ownerId" , "shipTo" ] ) ;
233+
234+ const outDir = await generate ( root , "postgres" , [ entityFile ( ) , queriesFile ( ) ] , tmpdir ( ) ) ;
235+ const entity = readFileSync ( allTs ( outDir ) . find ( ( f ) => f . endsWith ( "Parcel.ts" ) ) ! , "utf8" ) ;
236+ const table = entity . slice ( entity . indexOf ( "Table(\"parcels\"" ) , entity . indexOf ( "});" , entity . indexOf ( "Table(\"parcels\"" ) ) ) ;
237+ expect ( [ ...table . matchAll ( / ^ \s + \w + : \w + \( " ( [ ^ " ] + ) " / gm) ] . map ( ( m ) => m [ 1 ] ! ) . sort ( ) ) . toEqual ( [ "id" , "owner_id" , "ref" ] ) ;
238+ for ( const file of allTs ( outDir ) . filter ( ( f ) => / P a r c e l [ . \w ] * \. t s $ / . test ( f ) ) ) {
239+ expect ( readFileSync ( file , "utf8" ) ) . not . toMatch ( / s h i p T o ( S t r e e t | C i t y ) | s h i p _ t o _ / ) ;
240+ }
241+ } ) ;
242+ } ) ;
243+
199244describe ( "flattened storage: agent/ui.md reports the flat keys with their flags" , ( ) => {
200245 test ( "a filterable member's row is marked filterable and sortable" , async ( ) => {
201246 const page = renderAgentUiPage ( await load ( ) ) ;
0 commit comments