@@ -148,19 +148,20 @@ describe("buildExpectedSchema — @autoSet timestamp default", () => {
148148} ) ;
149149
150150// ---------------------------------------------------------------------------
151- // @dbColumnType uuid_array / text_array → native SQL array columns
152- // (metaobjects can't model Postgres arrays via field subtypes; the physical
153- // @dbColumnType escape hatch carries them, emitting uuid[] / text[].)
151+ // Native SQL array columns are DERIVED from `isArray` (dbColumnType slim-and-derive
152+ // Phase 1): the array-ness already lives on the field's `isArray` axis, so the DDL
153+ // derives `text[]` / `uuid[]` directly — no `@dbColumnType` escape hatch. The
154+ // removed `uuid_array` / `text_array` values now fail the loader (ERR_BAD_ATTR_VALUE).
154155// ---------------------------------------------------------------------------
155156
156- describe ( "buildExpectedSchema — native array columns (@dbColumnType *_array )" , ( ) => {
157+ describe ( "buildExpectedSchema — native array columns (derived from isArray )" , ( ) => {
157158 async function arrayCols ( ) {
158159 const doc = { "metadata.root" : { package : "acme" , children : [
159160 { "object.entity" : { name : "Bag" , children : [
160161 { "field.long" : { name : "id" } } ,
161162 { "identity.primary" : { "name" : "id" , "@fields" : "id" } } ,
162- { "field.string " : { name : "memberIds" , "@dbColumnType" : "uuid_array" } } ,
163- { "field.string" : { name : "tags" , "@dbColumnType" : "text_array" } } ,
163+ { "field.uuid " : { name : "memberIds" , isArray : true } } ,
164+ { "field.string" : { name : "tags" , isArray : true } } ,
164165 ] } } ,
165166 ] } } ;
166167 const { root, errors } = await new MetaDataLoader ( ) . load ( [
@@ -170,11 +171,45 @@ describe("buildExpectedSchema — native array columns (@dbColumnType *_array)",
170171 return new Map ( ( buildExpectedSchema ( root ) . tables [ 0 ] ?. columns ?? [ ] ) . map ( ( c ) => [ c . name , c ] ) ) ;
171172 }
172173
173- test ( "uuid_array → array of uuid; text_array → array of text" , async ( ) => {
174+ test ( "field.uuid isArray → uuid[]; field.string isArray → text[] " , async ( ) => {
174175 const byName = await arrayCols ( ) ;
175176 expect ( byName . get ( "member_ids" ) ?. sqlType ) . toEqual ( { kind : "array" , element : { kind : "uuid" } } ) ;
176177 expect ( byName . get ( "tags" ) ?. sqlType ) . toEqual ( { kind : "array" , element : { kind : "text" } } ) ;
177178 } ) ;
179+
180+ test ( "field.uuid scalar → uuid; field.string scalar (no maxLength) → text" , async ( ) => {
181+ const doc = { "metadata.root" : { package : "acme" , children : [
182+ { "object.entity" : { name : "Scalars" , children : [
183+ { "field.long" : { name : "id" } } ,
184+ { "identity.primary" : { "name" : "id" , "@fields" : "id" } } ,
185+ { "field.uuid" : { name : "ownerId" } } ,
186+ { "field.string" : { name : "label" } } ,
187+ ] } } ,
188+ ] } } ;
189+ const { root, errors } = await new MetaDataLoader ( ) . load ( [
190+ new InMemoryStringSource ( JSON . stringify ( doc ) ) ,
191+ ] ) ;
192+ expect ( errors ) . toHaveLength ( 0 ) ;
193+ const byName = new Map ( ( buildExpectedSchema ( root ) . tables [ 0 ] ?. columns ?? [ ] ) . map ( ( c ) => [ c . name , c ] ) ) ;
194+ expect ( byName . get ( "owner_id" ) ?. sqlType ) . toEqual ( { kind : "uuid" } ) ;
195+ expect ( byName . get ( "label" ) ?. sqlType ) . toEqual ( { kind : "text" } ) ;
196+ } ) ;
197+
198+ test ( "removed @dbColumnType:uuid_array / text_array now fail the loader (ERR_BAD_ATTR_VALUE)" , async ( ) => {
199+ for ( const removed of [ "uuid_array" , "text_array" ] ) {
200+ const doc = { "metadata.root" : { package : "acme" , children : [
201+ { "object.entity" : { name : "Bag" , children : [
202+ { "field.long" : { name : "id" } } ,
203+ { "identity.primary" : { "name" : "id" , "@fields" : "id" } } ,
204+ { "field.string" : { name : "x" , "@dbColumnType" : removed } } ,
205+ ] } } ,
206+ ] } } ;
207+ const { errors } = await new MetaDataLoader ( ) . load ( [
208+ new InMemoryStringSource ( JSON . stringify ( doc ) ) ,
209+ ] ) ;
210+ expect ( errors . some ( ( e ) => ( e as { code ?: string } ) . code === "ERR_BAD_ATTR_VALUE" ) ) . toBe ( true ) ;
211+ }
212+ } ) ;
178213} ) ;
179214
180215describe ( "buildExpectedSchema — indexes + FKs" , ( ) => {
0 commit comments