@@ -70,6 +70,58 @@ export const exportProductsStep = createStep(
7070 const fields = deduplicate ( [ "id" , "handle" , ...input . select ] )
7171 const { sales_channel_id, ..._filters } = input . filter ?? { }
7272
73+ // Pass 1: Collect unified keys across all batches
74+ const allKeys = new Set < string > ( )
75+ while ( true ) {
76+ if ( ! ! sales_channel_id ) {
77+ const { data : salesChannelProducts } = await query . graph ( {
78+ entity : "product_sales_channel" ,
79+ filters : {
80+ sales_channel_id,
81+ } ,
82+ fields : [ "product_id" ] ,
83+ pagination : {
84+ skip : page * pageSize ,
85+ take : pageSize ,
86+ } ,
87+ } )
88+
89+ _filters . id = salesChannelProducts . map ( ( product ) => product . product_id )
90+ }
91+
92+ const { data : products } = await query . graph ( {
93+ entity : "product" ,
94+ fields,
95+ filters : _filters ,
96+ // If sales channel is specified, we already paginated
97+ pagination : sales_channel_id
98+ ? undefined
99+ : {
100+ skip : page * pageSize ,
101+ take : pageSize ,
102+ } ,
103+ } )
104+
105+ if ( products . length === 0 ) {
106+ break
107+ }
108+
109+ const normalizedProducts = normalizeForExport ( products , { regions } )
110+ for ( const p of normalizedProducts ) {
111+ Object . keys ( p ) . forEach ( ( k ) => allKeys . add ( k ) )
112+ }
113+
114+ if ( products . length < pageSize ) {
115+ break
116+ }
117+
118+ page += 1
119+ }
120+
121+ const keysArray = Array . from ( allKeys )
122+
123+ // Pass 2: Stream data to CSV using the unified keys
124+ page = 0
73125 while ( true ) {
74126 if ( ! ! sales_channel_id ) {
75127 const { data : salesChannelProducts } = await query . graph ( {
@@ -108,6 +160,7 @@ export const exportProductsStep = createStep(
108160
109161 const batchCsv = json2csv ( normalizedProducts , {
110162 prependHeader : ! hasHeader ,
163+ keys : keysArray . length > 0 ? keysArray : undefined ,
111164 arrayIndexesAsKeys : true ,
112165 expandNestedObjects : true ,
113166 expandArrayObjects : true ,
0 commit comments