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
+15 -15
View File
@@ -1,7 +1,7 @@
import type { CsvLoaderOptions } from './loader.js';
import { csvToModule } from './loader.js';
import * as path from 'path';
import * as fs from 'fs';
import * as path from "path";
import * as fs from "fs";
import { csvToModule } from "./module-gen";
import { CsvLoaderOptions } from "./types";
export interface CsvRollupOptions extends CsvLoaderOptions {
/** Include pattern for CSV files (default: /\.csv$/) */
@@ -16,7 +16,7 @@ export interface CsvRollupOptions extends CsvLoaderOptions {
function matchesPattern(
id: string,
pattern: RegExp | string | Array<RegExp | string> | undefined
pattern: RegExp | string | Array<RegExp | string> | undefined,
): boolean {
if (!pattern) return true;
const patterns = Array.isArray(pattern) ? pattern : [pattern];
@@ -34,7 +34,7 @@ interface TransformResult {
}
interface EmitFileOptions {
type: 'asset';
type: "asset";
fileName: string;
source: string;
}
@@ -48,7 +48,7 @@ interface RollupPlugin {
transform: (
this: PluginContext,
code: string,
id: string
id: string,
) => TransformResult | null;
}
@@ -61,13 +61,13 @@ export function csvLoader(options: CsvRollupOptions = {}): RollupPlugin {
include = /\.csv$/,
exclude,
emitTypes = true,
typesOutputDir = '',
typesOutputDir = "",
writeToDisk = false,
...parseOptions
} = options;
return {
name: 'inline-schema-csv',
name: "inline-schema-csv",
transform(code: string, id: string) {
// Check if file matches the include/exclude patterns
@@ -75,12 +75,12 @@ export function csvLoader(options: CsvRollupOptions = {}): RollupPlugin {
if (exclude && matchesPattern(id, exclude)) return null;
// Only process .csv files
if (!id.endsWith('.csv')) return null;
if (!id.endsWith(".csv")) return null;
// Infer resource name from filename
const fileName = path.basename(id, '.csv').split('.')[0];
const fileName = path.basename(id, ".csv").split(".")[0];
const resourceName = fileName
.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
.replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ""))
.replace(/^(.)/, (_, char) => char.toUpperCase());
const result = csvToModule(code, {
@@ -95,8 +95,8 @@ export function csvLoader(options: CsvRollupOptions = {}): RollupPlugin {
// Emit type definition file if enabled
if (emitTypes && result.dts) {
const dtsPath = typesOutputDir
? path.join(typesOutputDir, path.basename(id) + '.d.ts')
: id + '.d.ts';
? path.join(typesOutputDir, path.basename(id) + ".d.ts")
: id + ".d.ts";
if (writeToDisk) {
// Write directly to disk
@@ -108,7 +108,7 @@ export function csvLoader(options: CsvRollupOptions = {}): RollupPlugin {
} else {
// Emit to Rollup's virtual module system
this.emitFile({
type: 'asset',
type: "asset",
fileName: dtsPath,
source: result.dts,
});