@@ -124,8 +124,15 @@ export function explodeField(rows: DataRow[], field: string): DataRow[] {
124124 const trimmed = value . trim ( ) ;
125125
126126 if ( trimmed . startsWith ( '[' ) && trimmed . endsWith ( ']' ) ) {
127- const parsed = JSON . parse ( trimmed ) as DataValue [ ] ;
128- return parsed . map ( ( item ) => ( { ...row , [ field ] : item } ) ) ;
127+ try {
128+ const parsed = JSON . parse ( trimmed ) as DataValue [ ] ;
129+
130+ if ( Array . isArray ( parsed ) ) {
131+ return parsed . map ( ( item ) => ( { ...row , [ field ] : item } ) ) ;
132+ }
133+ } catch {
134+ // Fall through to comma-split or single-row output.
135+ }
129136 }
130137
131138 if ( trimmed . includes ( ',' ) ) {
@@ -137,6 +144,56 @@ export function explodeField(rows: DataRow[], field: string): DataRow[] {
137144 } ) ;
138145}
139146
147+ export function validateReshape ( rows : DataRow [ ] , config : ReshapeConfig ) : string | null {
148+ if ( config . mode === 'none' ) {
149+ return null ;
150+ }
151+
152+ if ( config . mode === 'longer' ) {
153+ const fields = parseFields ( config . fields ) ;
154+
155+ if ( fields . length === 0 ) {
156+ return 'Pivot longer requires at least one field name.' ;
157+ }
158+
159+ if ( ! fields . some ( ( field ) => rows . some ( ( row ) => field in row ) ) ) {
160+ return `Pivot longer fields (${ fields . join ( ', ' ) } ) were not found in the current preview.` ;
161+ }
162+
163+ return null ;
164+ }
165+
166+ if ( config . mode === 'wider' ) {
167+ if ( config . namesFrom && rows . some ( ( row ) => config . namesFrom ! in row ) ) {
168+ return null ;
169+ }
170+
171+ const pivotFields = parseFields ( config . fields ) ;
172+
173+ if ( ! pivotFields . some ( ( field ) => rows . some ( ( row ) => field in row ) ) ) {
174+ return 'Pivot wider needs a long-form column or recognizable month columns in the current preview.' ;
175+ }
176+
177+ return null ;
178+ }
179+
180+ if ( config . mode === 'explode' ) {
181+ const field = config . field ?. trim ( ) ?? '' ;
182+
183+ if ( ! field ) {
184+ return 'Explode requires a field name.' ;
185+ }
186+
187+ if ( ! rows . some ( ( row ) => field in row ) ) {
188+ return `Explode field "${ field } " was not found in the current preview.` ;
189+ }
190+
191+ return null ;
192+ }
193+
194+ return null ;
195+ }
196+
140197export function applyReshape ( rows : DataRow [ ] , config : ReshapeConfig ) : ReshapeResult {
141198 let nextRows = rows ;
142199
0 commit comments