@@ -140,6 +140,62 @@ export async function registerRoutes(app: Express): Promise<Server> {
140140 }
141141 } ) ;
142142
143+ // TEST IMPORT ENDPOINT (no auth required)
144+ app . post ( "/api/test-import" , async ( req , res ) => {
145+ console . log ( "TEST IMPORT ENDPOINT HIT" ) ;
146+ try {
147+ console . log ( "Request body:" , JSON . stringify ( req . body ) ) ;
148+
149+ const { snippets } = req . body ;
150+
151+ if ( ! Array . isArray ( snippets ) ) {
152+ console . error ( "Invalid input: snippets is not an array" ) ;
153+ return res . status ( 400 ) . json ( {
154+ message : "Invalid input: snippets must be an array"
155+ } ) ;
156+ }
157+
158+ console . log ( `Processing ${ snippets . length } snippets for import` ) ;
159+
160+ // Try a direct database insertion for testing
161+ const testSnippet = snippets [ 0 ] ;
162+
163+ if ( ! testSnippet ) {
164+ return res . status ( 400 ) . json ( { message : "No snippets provided" } ) ;
165+ }
166+
167+ // Connect directly to the database
168+ const client = await pool . connect ( ) ;
169+ try {
170+ const result = await client . query (
171+ `INSERT INTO snippets (title, code, language, user_id, created_at, updated_at)
172+ VALUES ($1, $2, $3, 1, NOW(), NOW()) RETURNING id, title` ,
173+ [ testSnippet . title , testSnippet . code , testSnippet . language ]
174+ ) ;
175+
176+ console . log ( "Direct DB insert result:" , result . rows [ 0 ] ) ;
177+
178+ res . status ( 201 ) . json ( {
179+ message : "Test import successful" ,
180+ snippet : result . rows [ 0 ]
181+ } ) ;
182+ } catch ( dbError ) {
183+ console . error ( "Database error:" , dbError ) ;
184+ res . status ( 500 ) . json ( { message : "Database error" , error : dbError . message } ) ;
185+ } finally {
186+ client . release ( ) ;
187+ }
188+ } catch ( err ) {
189+ console . error ( "TEST IMPORT error:" , err ) ;
190+ res . status ( 500 ) . json ( {
191+ message : "Test import failed" ,
192+ error : err . message
193+ } ) ;
194+ }
195+ } ) ;
196+ // END OF TEST IMPORT ENDPOINT
197+
198+
143199 // ENHANCED EXPORT ENDPOINT
144200 app . get ( "/api/snippets/export" , authMiddleware , async ( req , res ) => {
145201 try {
@@ -174,64 +230,152 @@ export async function registerRoutes(app: Express): Promise<Server> {
174230 }
175231 } ) ;
176232
177- // NEW IMPORT ENDPOINT
178- app . post ( "/api/snippets/import" , authMiddleware , async ( req , res ) => {
179- try {
180- const { snippets } = req . body ;
181-
182- if ( ! Array . isArray ( snippets ) ) {
183- return res . status ( 400 ) . json ( {
184- message : "Invalid input: snippets must be an array"
185- } ) ;
186- }
187-
188- const importedSnippets = [ ] ;
189- const userId = ( req as any ) . user . id ;
190-
191- for ( const snippetData of snippets ) {
233+
234+ // NEW IMPORT ENDPOINT with enhanced logging
235+ app . post ( "/api/snippets/import" , authMiddleware , async ( req , res ) => {
236+ try {
237+ console . log ( "[IMPORT] Import request received" ) ;
238+
239+ // Check authentication
240+ const userId = ( req as any ) . user ?. id ;
241+ console . log ( "[IMPORT] Auth user ID:" , userId ) ;
242+
243+ if ( ! userId ) {
244+ console . error ( "[IMPORT] No user ID found in request" ) ;
245+ return res . status ( 401 ) . json ( { message : "Authentication required" } ) ;
246+ }
247+
248+ // Log request body
249+ console . log ( "[IMPORT] Request body structure:" , JSON . stringify ( {
250+ snippetsArrayLength : Array . isArray ( req . body . snippets ) ? req . body . snippets . length : 'not an array' ,
251+ firstSnippetSample : Array . isArray ( req . body . snippets ) && req . body . snippets . length > 0
252+ ? { title : req . body . snippets [ 0 ] . title , language : req . body . snippets [ 0 ] . language }
253+ : 'no snippets'
254+ } ) ) ;
255+
256+ const { snippets } = req . body ;
257+
258+ if ( ! Array . isArray ( snippets ) ) {
259+ console . error ( "[IMPORT] Invalid input: snippets is not an array" ) ;
260+ return res . status ( 400 ) . json ( {
261+ message : "Invalid input: snippets must be an array"
262+ } ) ;
263+ }
264+
265+ console . log ( `[IMPORT] Processing ${ snippets . length } snippets for import` ) ;
266+
267+ // Track results
268+ const importResults = {
269+ success : [ ] ,
270+ failed : [ ]
271+ } ;
272+
273+ // Process each snippet
274+ for ( let i = 0 ; i < snippets . length ; i ++ ) {
275+ try {
276+ const snippetData = snippets [ i ] ;
277+ console . log ( `[IMPORT] Processing snippet ${ i + 1 } /${ snippets . length } :` ,
278+ JSON . stringify ( {
279+ title : snippetData . title || 'untitled' ,
280+ language : snippetData . language || 'unknown' ,
281+ codeLength : snippetData . code ? snippetData . code . length : 0 ,
282+ hasDescription : ! ! snippetData . description ,
283+ tagsCount : Array . isArray ( snippetData . tags ) ? snippetData . tags . length : 0
284+ } )
285+ ) ;
286+
287+ // Ensure required fields are present
288+ if ( ! snippetData . title || ! snippetData . code ) {
289+ console . error ( `[IMPORT] Snippet ${ i + 1 } missing required fields:` ,
290+ JSON . stringify ( {
291+ hasTitle : ! ! snippetData . title ,
292+ hasCode : ! ! snippetData . code
293+ } )
294+ ) ;
295+ importResults . failed . push ( {
296+ index : i ,
297+ title : snippetData . title || 'untitled' ,
298+ reason : "Missing required fields"
299+ } ) ;
300+ continue ;
301+ }
302+
303+ // Format the snippet to match our database schema
304+ const formattedSnippet = {
305+ title : snippetData . title ,
306+ code : snippetData . code ,
307+ language : snippetData . language || null ,
308+ description : snippetData . description || null ,
309+ tags : Array . isArray ( snippetData . tags ) ? snippetData . tags : null ,
310+ userId : userId , // Use validated user ID from auth
311+ isFavorite : typeof snippetData . isFavorite === 'boolean' ? snippetData . isFavorite : false ,
312+ isPublic : typeof snippetData . isPublic === 'boolean' ? snippetData . isPublic : false
313+ } ;
314+
315+ console . log ( `[IMPORT] Formatted snippet ${ i + 1 } :` , JSON . stringify ( {
316+ title : formattedSnippet . title ,
317+ language : formattedSnippet . language ,
318+ userId : formattedSnippet . userId ,
319+ tagsCount : Array . isArray ( formattedSnippet . tags ) ? formattedSnippet . tags . length : 0
320+ } ) ) ;
321+
322+ // Validate with schema
192323 try {
193- // Ensure required fields are present
194- if ( ! snippetData . title || ! snippetData . code ) {
195- console . error ( "[IMPORT] Skipping snippet due to missing required fields:" , snippetData . title || "Untitled" ) ;
196- continue ;
197- }
198-
199- // Format the snippet to match our database schema
200- const formattedSnippet = {
201- title : snippetData . title ,
202- code : snippetData . code ,
203- language : snippetData . language || null ,
204- description : snippetData . description || null ,
205- tags : Array . isArray ( snippetData . tags ) ? snippetData . tags : null ,
206- userId : userId ,
207- isFavorite : typeof snippetData . isFavorite === 'boolean' ? snippetData . isFavorite : false ,
208- isPublic : typeof snippetData . isPublic === 'boolean' ? snippetData . isPublic : false
209- } ;
210-
211- // Validate with schema
324+ console . log ( `[IMPORT] Validating snippet ${ i + 1 } with schema` ) ;
212325 const validatedSnippet = insertSnippetSchema . parse ( formattedSnippet ) ;
326+ console . log ( `[IMPORT] Schema validation passed for snippet ${ i + 1 } ` ) ;
213327
214328 // Create the snippet
329+ console . log ( `[IMPORT] Calling storage.createSnippet for snippet ${ i + 1 } ` ) ;
215330 const createdSnippet = await storage . createSnippet ( validatedSnippet ) ;
216- importedSnippets . push ( createdSnippet ) ;
217- } catch ( snippetError ) {
218- console . error ( "[IMPORT] Error importing snippet:" , snippetError ) ;
219- // Continue with other snippets even if one fails
331+ console . log ( `[IMPORT] Snippet ${ i + 1 } created successfully with ID:` , createdSnippet . id ) ;
332+
333+ importResults . success . push ( createdSnippet ) ;
334+ } catch ( validationError : any ) {
335+ console . error ( `[IMPORT] Schema validation error for snippet ${ i + 1 } :` , validationError ) ;
336+ importResults . failed . push ( {
337+ index : i ,
338+ title : snippetData . title ,
339+ reason : validationError instanceof z . ZodError
340+ ? JSON . stringify ( validationError . errors )
341+ : validationError . message
342+ } ) ;
343+ continue ;
220344 }
345+ } catch ( snippetError : any ) {
346+ console . error ( `[IMPORT] Error processing snippet ${ i + 1 } :` , snippetError ) ;
347+ importResults . failed . push ( {
348+ index : i ,
349+ title : snippets [ i ] ?. title || 'unknown' ,
350+ reason : snippetError . message
351+ } ) ;
352+ // Continue with other snippets even if one fails
221353 }
222-
223- res . status ( 201 ) . json ( {
224- message : `Successfully imported ${ importedSnippets . length } snippets.` ,
225- snippets : importedSnippets
226- } ) ;
227- } catch ( err : any ) {
228- console . error ( "[IMPORT] POST /api/snippets/import error:" , err ) ;
229- res . status ( 500 ) . json ( {
230- message : "Failed to import snippets" ,
231- error : err . message
232- } ) ;
233354 }
234- } ) ;
355+
356+ console . log ( "[IMPORT] Import completed. Results:" , JSON . stringify ( {
357+ successCount : importResults . success . length ,
358+ failedCount : importResults . failed . length
359+ } ) ) ;
360+
361+ // Return appropriate response
362+ res . status ( 201 ) . json ( {
363+ message : `Successfully imported ${ importResults . success . length } snippets. ${ importResults . failed . length > 0 ? `Failed to import ${ importResults . failed . length } snippets.` : '' } ` ,
364+ success : importResults . success . map ( s => ( { id : s . id , title : s . title } ) ) ,
365+ failed : importResults . failed
366+ } ) ;
367+ } catch ( err : any ) {
368+ console . error ( "[IMPORT] POST /api/snippets/import error:" , err ) ;
369+ res . status ( 500 ) . json ( {
370+ message : "Failed to import snippets" ,
371+ error : err . message
372+ } ) ;
373+ }
374+ } ) ;
375+
376+ // ────────────────────────────────────────────────────────────────
377+ // END OF IMPORT ENDPOINT
378+ // ────────────────────────────────────────────────────────────────
235379
236380 app . get ( "/api/snippets/:id" , async ( req , res ) => {
237381 try {
0 commit comments