From 4eb6a17e9fbd0b893cb79789a1ee107d9b320a19 Mon Sep 17 00:00:00 2001 From: hypercross Date: Sun, 5 Apr 2026 12:38:33 +0800 Subject: [PATCH] refactor: table name deduction & readonly type --- src/csv-loader/loader.ts | 37 ++++++++++++++++++++++--------------- src/csv-loader/rollup.ts | 7 +++++++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/csv-loader/loader.ts b/src/csv-loader/loader.ts index e6819ee..100538e 100644 --- a/src/csv-loader/loader.ts +++ b/src/csv-loader/loader.ts @@ -53,17 +53,17 @@ function schemaToTypeString(schema: Schema): string { if (schema.element.type === 'tuple') { const tupleElements = schema.element.elements.map((el) => { const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; + return el.name ? `readonly ${el.name}: ${typeStr}` : typeStr; }); - return `[${tupleElements.join(', ')}]`; + return `readonly [${tupleElements.join(', ')}]`; } - return `${schemaToTypeString(schema.element)}[]`; + return `readonly ${schemaToTypeString(schema.element)}[]`; case 'tuple': const tupleElements = schema.elements.map((el) => { const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; + return el.name ? `readonly ${el.name}: ${typeStr}` : typeStr; }); - return `[${tupleElements.join(', ')}]`; + return `readonly [${tupleElements.join(', ')}]`; default: return 'unknown'; } @@ -76,15 +76,16 @@ function generateTypeDefinition( resourceName: string, propertyConfigs: PropertyConfig[] ): string { + const typeName = resourceName ? `${resourceName}Table` : 'Table'; const properties = propertyConfigs - .map((config) => ` ${config.name}: ${schemaToTypeString(config.schema)};`) + .map((config) => ` readonly ${config.name}: ${schemaToTypeString(config.schema)};`) .join('\n'); - - return `type Table = { -${properties} - }[]; -declare const data: Table; + return `type ${typeName} = readonly { +${properties} +}[]; + +declare const data: ${typeName}; export default data; `; } @@ -99,7 +100,7 @@ export default data; */ export function parseCsv( content: string, - options: CsvLoaderOptions = {} + options: CsvLoaderOptions & { resourceName?: string } = {} ): CsvParseResult { const delimiter = options.delimiter ?? ','; const quote = options.quote ?? '"'; @@ -174,7 +175,7 @@ export function parseCsv( }; if (emitTypes) { - result.typeDefinition = generateTypeDefinition('', propertyConfigs); + result.typeDefinition = generateTypeDefinition(options.resourceName || '', propertyConfigs); } return result; @@ -190,7 +191,7 @@ export function parseCsv( */ export function csvToModule( content: string, - options: CsvLoaderOptions = {} + options: CsvLoaderOptions & { resourceName?: string } = {} ): { js: string; dts?: string } { const result = parseCsv(content, options); @@ -212,7 +213,13 @@ export default function csvLoader( const typesOutputDir = options?.typesOutputDir ?? ''; const writeToDisk = options?.writeToDisk ?? false; - const result = parseCsv(content, options); + // Infer resource name from filename + const fileName = path.basename(this.resourcePath, '.csv').split('.')[0]; + const resourceName = fileName + .replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '') + .replace(/^(.)/, (_, char) => char.toUpperCase()); + + const result = parseCsv(content, { ...options, resourceName }); // Emit type definition file if enabled if (emitTypes && result.typeDefinition) { diff --git a/src/csv-loader/rollup.ts b/src/csv-loader/rollup.ts index 07a03e6..930088c 100644 --- a/src/csv-loader/rollup.ts +++ b/src/csv-loader/rollup.ts @@ -73,9 +73,16 @@ export function csvLoader(options: CsvRollupOptions = {}): RollupPlugin { // Only process .csv files if (!id.endsWith('.csv')) return null; + // Infer resource name from filename + const fileName = path.basename(id, '.csv').split('.')[0]; + const resourceName = fileName + .replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '') + .replace(/^(.)/, (_, char) => char.toUpperCase()); + const result = csvToModule(code, { ...parseOptions, emitTypes, + resourceName, }); // Emit type definition file if enabled