Skip to content

Commit 2347d39

Browse files
committed
chore: 🐛 fixed bugs
update ESLint configuration and add lint error logging and schema fetching issues
1 parent beed11b commit 2347d39

File tree

9 files changed

+207
-302
lines changed

9 files changed

+207
-302
lines changed

app/api/schemas/[name]/route.ts

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NextRequest, NextResponse } from "next/server";
1+
import { NextResponse } from "next/server";
22
import fs from "fs/promises";
33
import path from "path";
44
import { parse } from "jsonc-parser";
@@ -8,52 +8,61 @@ const getSchemaDirectory = () => {
88
return path.join(process.cwd(), "schemas", "v1");
99
};
1010

11-
interface Context {
12-
params: {
13-
name: string;
14-
};
11+
// Generate static paths for all schemas (for preloading in Vercel)
12+
export async function generateStaticParams() {
13+
try {
14+
const directory = getSchemaDirectory();
15+
const files = await fs.readdir(directory);
16+
17+
// Filter to only include JSON files and exclude Zone.Identifier files
18+
const schemaNames = files.filter(file =>
19+
file.endsWith('.json') && !file.includes(':Zone.Identifier')
20+
);
21+
22+
// Return the list of params for each schema
23+
return schemaNames.map(filename => ({
24+
name: filename.replace('.json', ''),
25+
}));
26+
} catch (error) {
27+
console.error("Error generating static params:", error);
28+
return []; // Return empty array if error occurs
29+
}
1530
}
1631

32+
// Updated type signature for Next.js 15.3.1
1733
export async function GET(
18-
request: NextRequest,
19-
{ params }: Context
34+
request: Request,
35+
context: { params: { name: string } }
2036
) {
21-
console.log("[API /api/schemas/[name]] Received params:", params);
22-
23-
// Validate that params.name is a string and not an object
24-
if (
25-
!params.name ||
26-
typeof params.name !== "string" ||
27-
params.name === "[object Object]"
28-
) {
29-
console.log(
30-
"[API /api/schemas/[name]] Invalid name received:",
31-
params.name,
32-
);
33-
return NextResponse.json(
34-
{ error: "Invalid schema name provided" },
35-
{ status: 400 },
36-
);
37-
}
38-
39-
// Ensure the file has .json extension
40-
const schemaName = params.name.endsWith(".json")
41-
? params.name
42-
: `${params.name}.json`;
43-
44-
console.log(
45-
`[API /api/schemas/${schemaName}] Reading file: ${path.join(getSchemaDirectory(), schemaName)}`,
46-
);
47-
4837
try {
38+
const { params } = context;
39+
40+
// Ensure params.name is a string
41+
const schemaName = typeof params.name === 'string'
42+
? params.name.endsWith('.json')
43+
? params.name
44+
: `${params.name}.json`
45+
: '';
46+
47+
if (!schemaName) {
48+
console.log("[API /api/schemas/[name]] Invalid or missing name parameter");
49+
return NextResponse.json(
50+
{ error: "Invalid schema name provided" },
51+
{ status: 400 },
52+
);
53+
}
54+
55+
console.log(`[API /api/schemas/${schemaName}] Reading file: ${path.join(getSchemaDirectory(), schemaName)}`);
56+
4957
const filePath = path.join(getSchemaDirectory(), schemaName);
5058

5159
// Check if file exists first
5260
try {
5361
await fs.access(filePath);
5462
} catch (error) {
63+
const errorMsg = error instanceof Error ? error.message : String(error);
5564
console.log(
56-
`[API /api/schemas/${schemaName}] Error reading schema file: ${error}`,
65+
`[API /api/schemas/${schemaName}] Error reading schema file: ${errorMsg}`,
5766
);
5867
return NextResponse.json(
5968
{ error: `Schema file not found: ${schemaName}` },
@@ -65,23 +74,28 @@ export async function GET(
6574

6675
// Parse JSONC (JSON with comments) for validation
6776
try {
68-
const parsedSchema = parse(fileContent);
77+
const parsedSchema = parse(fileContent) as Record<string, unknown>;
6978
return NextResponse.json(parsedSchema);
7079
} catch (error) {
80+
const errorMsg = error instanceof Error ? error.message : String(error);
7181
console.error(
7282
`[API /api/schemas/${schemaName}] JSON parsing error:`,
73-
error,
83+
errorMsg,
7484
);
7585
return NextResponse.json(
7686
{ error: "Invalid JSON schema format" },
7787
{ status: 400 },
7888
);
7989
}
8090
} catch (error) {
81-
console.error(`[API /api/schemas/${schemaName}] Server error:`, error);
91+
const errorMsg = error instanceof Error ? error.message : String(error);
92+
console.error(`[API /api/schemas/[name]] Server error:`, errorMsg);
8293
return NextResponse.json(
8394
{ error: "Failed to read schema file" },
8495
{ status: 500 },
8596
);
8697
}
8798
}
99+
100+
// Use static in production for export compatibility
101+
export const dynamic = 'force-static';

app/api/schemas/route.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,39 @@ import { NextResponse } from "next/server";
22
import fs from "fs/promises";
33
import path from "path";
44

5-
// Get the schemas directory
5+
// Get the schemas directory path
66
const getSchemasDirectory = () => {
77
return path.join(process.cwd(), "schemas", "v1");
88
};
99

10-
// Interface for schema objects
11-
interface SchemaInfo {
12-
name: string;
13-
filename: string;
14-
}
15-
16-
export async function GET() {
17-
const schemasDir = path.join(process.cwd(), "schemas", "v1");
18-
console.log(`[API /api/schemas] Reading directory: ${schemasDir}`);
19-
10+
export async function GET(request: Request) {
11+
console.log("[API /api/schemas] Getting list of schemas");
12+
2013
try {
21-
const files = await fs.readdir(schemasDir);
22-
console.log(`[API /api/schemas] Found files: ${files.join(", ")}`);
23-
24-
const jsonFiles = files.filter(
25-
(file) => file.endsWith(".json") && !file.includes(":Zone.Identifier"),
26-
);
27-
console.log(
28-
`[API /api/schemas] Filtered JSON files: ${jsonFiles.join(", ")}`,
14+
const directory = getSchemasDirectory();
15+
const files = await fs.readdir(directory);
16+
17+
// Filter to only include JSON files and exclude Zone.Identifier files
18+
const schemaNames = files.filter(file =>
19+
file.endsWith('.json') && !file.includes(':Zone.Identifier')
2920
);
30-
31-
const schemas = jsonFiles.map((filename) => ({
32-
name: filename.replace(".json", ""),
21+
22+
console.log(`[API /api/schemas] Found ${schemaNames.length} schemas:`, schemaNames);
23+
24+
// Format the response to match what the client expects
25+
const schemas = schemaNames.map(filename => ({
26+
name: filename.replace('.json', ''),
3327
filename,
3428
}));
35-
36-
console.log(
37-
`[API /api/schemas] Mapped schemas: ${JSON.stringify(schemas, null, 2)}`,
38-
);
39-
29+
4030
return NextResponse.json(schemas);
4131
} catch (error) {
42-
console.error("[API /api/schemas] Error reading schema directory:", error);
32+
const errorMsg = error instanceof Error ? error.message : String(error);
33+
console.error("[API /api/schemas] Error reading schemas directory:", errorMsg);
34+
4335
return NextResponse.json(
4436
{ error: "Failed to read schemas directory" },
45-
{ status: 500 },
37+
{ status: 500 }
4638
);
4739
}
4840
}

components/csv-validator.tsx

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ import ValidationResults from "@/components/validation-results";
5656
import Image from "next/image";
5757
import { Switch } from "@/components/ui/switch";
5858
import { Label } from "@/components/ui/label";
59-
import { getSchemasList, getSchemaByName, generateSchemaDocumentation } from '@/lib/api-client';
59+
import { getSchemasList, getSchemaByName, generateSchemaDocumentation, type SchemaObject } from '@/lib/api-client';
6060

6161
// --- Web Worker Setup ---
6262
const getWorker = (() => {
@@ -184,16 +184,6 @@ interface RowValidationResults {
184184
warnings: ValidationIssue[];
185185
}
186186

187-
// Interface for the schema list API response
188-
interface SchemaObject {
189-
// Define the object structure
190-
name: string;
191-
filename: string;
192-
}
193-
interface SchemaListResponse {
194-
schemas: SchemaObject[]; // Expect an array of SchemaObjects
195-
}
196-
197187
// Interface for single schema content API response
198188
interface SchemaContentResponse {
199189
content: Record<string, unknown> | string;
@@ -499,51 +489,41 @@ export default function CsvValidator() {
499489
// --- Effect to fetch schema list on mount --- // Keep uncommented for now
500490
useEffect(() => {
501491
const fetchSchemaList = async () => {
492+
if (schemaListCache.list) {
493+
console.log("Using cached schema list");
494+
setAvailableSchemaNames(schemaListCache.list);
495+
setIsLoadingSchemaList(false);
496+
return;
497+
}
498+
502499
setIsLoadingSchemaList(true);
500+
503501
try {
504-
if (schemaListCache.list) {
505-
setAvailableSchemaNames(schemaListCache.list);
502+
console.log("Fetching schema list...");
503+
const schemas: SchemaObject[] = await getSchemasList();
504+
console.log("Fetched schemas:", schemas);
505+
506+
if (!schemas || !Array.isArray(schemas) || schemas.length === 0) {
506507
setIsLoadingSchemaList(false);
507508
return;
508509
}
509-
510-
// Use our new API client instead of direct fetch
511-
const data = await getSchemasList();
512-
513-
// Ensure data is an array before sorting/mapping
514-
if (!Array.isArray(data)) {
515-
throw new Error("API response for schemas is not an array.");
516-
}
517-
// Sort based on the 'name' property for user-friendly display
518-
const sortedSchemaObjects = data.sort((a, b) =>
519-
a.name.localeCompare(b.name),
520-
);
521-
// Extract filenames for internal use (state, selection values)
522-
const schemaFilenames = sortedSchemaObjects.map((s) => s.filename);
523510

524-
schemaListCache.list = schemaFilenames; // Cache the filenames
525-
setAvailableSchemaNames(schemaFilenames); // Set state with filenames
526-
527-
// Automatically select the first schema *filename* if available
528-
if (schemaFilenames.length > 0 && !selectedSchemaName) {
529-
setSelectedSchemaName(schemaFilenames[0]); // Auto-select the filename string
530-
}
531-
} catch (error: unknown) {
511+
// Extract schema names for dropdown
512+
const schemaNames: string[] = schemas.map((schema) => schema.name);
513+
setAvailableSchemaNames(schemaNames);
514+
// Cache for future use
515+
schemaListCache.list = schemaNames;
516+
// Make sure to set loading to false after successful load
517+
setIsLoadingSchemaList(false);
518+
} catch (error) {
532519
console.error("Error fetching schema list:", error);
533-
void toast({
534-
title: "Error",
535-
description:
536-
"Could not fetch the list of available schemas. Please check the API or try again later.",
537-
variant: "destructive",
538-
});
539-
} finally {
540520
setIsLoadingSchemaList(false);
541521
}
542522
};
543523

544524
void fetchSchemaList();
545525
// Add dependencies here if needed, e.g., if fetchSchemaList depends on props or other state
546-
}, [toast, selectedSchemaName]); // Added toast and selectedSchemaName as dependencies
526+
}, [toast]); // Added toast as dependency
547527

548528
// --- Effect to fetch schema content when selection changes --- // Uncomment
549529
useEffect(() => {

0 commit comments

Comments
 (0)