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:
@@ -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;
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user