Skip to content

Commit 0c2c9f5

Browse files
committed
add updated routes.ts
1 parent acdec9e commit 0c2c9f5

File tree

1 file changed

+194
-50
lines changed

1 file changed

+194
-50
lines changed

server/routes.ts

Lines changed: 194 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)