inline-schema/src/csv-loader/type-gen.ts

70 lines
2.0 KiB
TypeScript

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;
`;
}