refactor(csv-loader): decouple reference resolution and module

generation

Extract reference resolution logic, type generation, and module
generation into dedicated modules to improve maintainability and
clean up the core loader.
This commit is contained in:
2026-04-20 00:48:01 +08:00
parent eeaac92e39
commit f94e9b68e4
9 changed files with 1061 additions and 1012 deletions
+69
View File
@@ -0,0 +1,69 @@
import * as path from "path";
import { schemaToTypeString } from "../index.js";
import type { PropertyConfig } from "./types.js";
/**
* Generate TypeScript interface for the CSV data
*/
export function generateTypeDefinition(
resourceName: string,
propertyConfigs: PropertyConfig[],
references: Set<string>,
currentFilePath?: string,
): string {
const typeName = resourceName ? `${resourceName}Table` : "Table";
const currentTableName = currentFilePath
? path.basename(currentFilePath, path.extname(currentFilePath))
: undefined;
const singularType = resourceName
? resourceName.charAt(0).toUpperCase() + resourceName.slice(1)
: `${typeName}[number]`;
// Generate import statements for referenced tables
const imports: string[] = [];
const resourceNames = new Map<string, string>();
references.forEach((tableName) => {
if (tableName === currentTableName) {
resourceNames.set(tableName, singularType);
return;
}
// Convert table name to type name by capitalizing
const typeBase = tableName.charAt(0).toUpperCase() + tableName.slice(1);
resourceNames.set(tableName, typeBase);
// Generate import path based on current file path
let importPath: string;
if (currentFilePath) {
importPath = `./${tableName}.csv`;
} else {
importPath = `../${tableName}.csv`;
}
imports.push(`import type { ${typeBase} } from '${importPath}';`);
});
const importSection = imports.length > 0 ? imports.join("\n") + "\n\n" : "";
const properties = propertyConfigs
.map(
(config) =>
` readonly ${config.name}: ${schemaToTypeString(config.schema, resourceNames)};`,
)
.join("\n");
let exportAlias = "";
if (resourceName) {
const singularType =
resourceName.charAt(0).toUpperCase() + resourceName.slice(1);
exportAlias = `\nexport type ${singularType} = ${typeName}[number];`;
}
return `${importSection}type ${typeName} = readonly {
${properties}
}[];
${exportAlias}
declare function getData(): ${typeName};
export default getData;
`;
}